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

Revision 1234, 7.4 kB (checked in by holin, 16 years ago)

fix gcc 4.3 compile errors and some warnings (largely from Adrian Knoth)

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