root/trunk/libffado/tests/test-messagequeue.cpp

Revision 2088, 7.4 kB (checked in by jwoithe, 2 months ago)

More fixes for compilation under gcc 4.7. Patch supplied by "oget". Fixes reopened ticket #344.

Line 
1 /*
2  * Copyright (C) 2005-2008 by Pieter Palmers
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 2 of the License, or
12  * (at your option) version 3 of the License.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 #include "debugmodule/debugmodule.h"
25
26 #include "libutil/PosixMessageQueue.h"
27 #include "libutil/Functors.h"
28
29 #include <argp.h>
30 #include <stdlib.h>
31 #include <iostream>
32 #include <signal.h>
33 #include <unistd.h>
34
35 #include <semaphore.h>
36 #include <cstring>
37
38 using namespace Util;
39
40 DECLARE_GLOBAL_DEBUG_MODULE;
41
42 #define MAX_ARGS 2
43
44 int run=1;
45 int lastsig=-1;
46 static void sighandler (int sig)
47 {
48     run = 0;
49 }
50
51 sem_t peep_sem;
52
53 ////////////////////////////////////////////////
54 // arg parsing
55 ////////////////////////////////////////////////
56 const char *argp_program_version = "test-messagequeue 0.1";
57 const char *argp_program_bug_address = "<ffado-devel@lists.sf.net>";
58 static char doc[] = "test-avccmd -- test program to test the message queues.";
59 static char args_doc[] = "DIRECTION";
60 static struct argp_option options[] = {
61     {"verbose",  'v', "level",    0,  "Produce verbose output" },
62    { 0 }
63 };
64
65 struct arguments
66 {
67     arguments()
68         : nargs ( 0 )
69         , verbose( false )
70         {
71             args[0] = 0;
72         }
73
74     char* args[MAX_ARGS];
75     int   nargs;
76     long int verbose;
77 } arguments;
78
79 // Parse a single option.
80 static error_t
81 parse_opt( int key, char* arg, struct argp_state* state )
82 {
83     // Get the input argument from `argp_parse', which we
84     // know is a pointer to our arguments structure.
85     struct arguments* arguments = ( struct arguments* ) state->input;
86
87     char* tail;
88     errno = 0;
89     switch (key) {
90     case 'v':
91         if (arg) {
92             arguments->verbose = strtol( arg, &tail, 0 );
93             if ( errno ) {
94                 fprintf( stderr,  "Could not parse 'verbose' argument\n" );
95                 return ARGP_ERR_UNKNOWN;
96             }
97         }
98         break;
99     case ARGP_KEY_ARG:
100         if (state->arg_num >= MAX_ARGS) {
101             // Too many arguments.
102             argp_usage (state);
103         }
104         arguments->args[state->arg_num] = arg;
105         arguments->nargs++;
106         break;
107     case ARGP_KEY_END:
108         if(arguments->nargs <= 0) {
109             printMessage("not enough arguments\n");
110             return -1;
111         }
112         break;
113     default:
114         return ARGP_ERR_UNKNOWN;
115     }
116     return 0;
117 }
118
119 static struct argp argp = { options, parse_opt, args_doc, doc };
120
121 class TestMessage : public Util::PosixMessageQueue::Message
122 {
123 public:
124     TestMessage()
125     : Message()
126     , m_prio( 0 )
127     , m_length( 64 )
128     , m_cnt( 0 )
129     {};
130     virtual ~TestMessage()
131     {};
132
133     virtual unsigned int getPriority()
134         {return m_prio;};
135     virtual unsigned int getLength() {
136         return m_length;
137     };
138
139     virtual bool serialize(char *buff) {
140         snprintf(buff, m_length, "cnt: %d", m_cnt++);
141         return true;
142     }
143
144     virtual bool deserialize(const char *buff, unsigned int length, unsigned prio) {
145         char tmp[length+1];
146         snprintf(tmp, length, "%s", buff);
147         tmp[length]=0;
148         printMessage("got message: '%s', prio %u\n", tmp, prio);
149         m_prio = prio;
150         return true;
151     };
152
153 private:
154     unsigned m_prio;
155     unsigned int m_length;
156     int m_cnt;
157 };
158
159 void peep() {
160      printMessage("peep...\n");
161      sem_post(&peep_sem);
162 }
163
164 ///////////////////////////
165 // main
166 //////////////////////////
167 int
168 main(int argc, char **argv)
169 {
170     int rv=0;
171     signal (SIGINT, sighandler);
172     signal (SIGPIPE, sighandler);
173
174     // arg parsing
175     if ( argp_parse ( &argp, argc, argv, 0, 0, &arguments ) ) {
176         fprintf( stderr, "Could not parse command line\n" );
177         exit(-1);
178     }
179
180     setDebugLevel(arguments.verbose);
181
182     errno = 0;
183     char* tail;
184     long int direction = strtol( arguments.args[0], &tail, 0 );
185     if ( errno ) {
186         fprintf( stderr,  "Could not parse direction argument\n" );
187         exit(-1);
188     }
189
190     if(sem_init(&peep_sem, 0, 0)) {
191         debugError("Could not init wait sem\n");
192         exit(-1);
193     }
194
195     printMessage("Testing message queue direction %ld\n", direction);
196
197     Util::Functor* peepfunc = NULL;
198
199     PosixMessageQueue p = PosixMessageQueue("testqueue1");
200     p.setVerboseLevel(arguments.verbose);
201     if(direction == 0) {
202         if(!p.Create(PosixMessageQueue::eD_WriteOnly)) {
203             debugError("Could not create queue\n");
204             exit(-1);
205         }
206     } else {
207         if(!p.Open(PosixMessageQueue::eD_ReadOnly, PosixMessageQueue::eB_NonBlocking)) {
208             debugError("Could not open queue\n");
209             exit(-1);
210         }
211         peepfunc = new Util::CallbackFunctor0< void (*)() >
212                     ( &peep, false );
213         if ( !peepfunc ) {
214             debugError( "Could not create peep handler\n" );
215             exit(-1);
216         }
217         if(!p.setNotificationHandler(peepfunc)) {
218             debugError("Could not set Notification Handler\n");
219              exit(-1);
220         }
221 //         if(!p.enableNotification()) {
222 //             debugError("Could not enable Notification\n");
223 //             exit(-1);
224 //         }
225     }
226
227     #define TIME_TO_SLEEP 1000*100
228     TestMessage m = TestMessage();
229     //m.setVerboseLevel(arguments.verbose);
230     run=1;
231     while(run) {
232         if(direction == 0) {
233             printMessage("sending...\n");
234             if(p.Send(m) != PosixMessageQueue::eR_OK) {
235                 debugError("Could not send to queue\n");
236                 goto out_err;
237             }
238             usleep(TIME_TO_SLEEP);
239         } else {
240             printMessage("receiving...\n");
241             printMessage(" enable notification...\n");
242             // first enable notification
243             if(!p.enableNotification()) {
244                 debugError("Could not enable Notification\n");
245                 goto out_err;
246             }
247             // then read all there is to read
248             printMessage(" reading...\n");
249             enum PosixMessageQueue::eResult ret;
250             while((ret = p.Receive(m)) == PosixMessageQueue::eR_OK) {
251                 // nothing
252             }
253             if (ret != PosixMessageQueue::eR_OK && ret != PosixMessageQueue::eR_Again) {
254                 debugError("Could not receive from queue\n");
255                 goto out_err;
256             }
257             // wait for a notification
258             printMessage(" waiting...\n");
259             if(sem_wait(&peep_sem)) {
260                 printMessage(" error: %s\n", strerror(errno));
261                 goto out_err;
262             }
263         }
264     }
265
266 cleanup:
267     if(peepfunc) {
268         if(!p.disableNotification()) {
269             debugError("Could not disable Notification\n");
270         }
271         if(!p.unsetNotificationHandler()) {
272             debugError("Could not unset Notification Handler\n");
273              exit(-1);
274         }
275         delete peepfunc;
276     }
277    
278     sem_destroy(&peep_sem);
279     return rv;
280
281 out_err:
282     rv=-1;
283     goto cleanup;
284
285 }
286
Note: See TracBrowser for help on using the browser.