root/trunk/libffado/src/libieee1394/IsoHandlerManager.cpp

Revision 870, 22.3 kB (checked in by ppalmers, 13 years ago)

try and work around buffer size issues in raw1394

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 "config.h"
25 #include "IsoHandlerManager.h"
26 #include "ieee1394service.h"
27 #include "IsoHandler.h"
28 #include "libstreaming/generic/StreamProcessor.h"
29
30 #include "libutil/Atomic.h"
31
32 #include "libutil/PosixThread.h"
33
34 #include <assert.h>
35
36 IMPL_DEBUG_MODULE( IsoHandlerManager, IsoHandlerManager, DEBUG_LEVEL_NORMAL );
37
38 using namespace Streaming;
39
40 IsoHandlerManager::IsoHandlerManager(Ieee1394Service& service)
41    : m_State(E_Created)
42    , m_service( service )
43    , m_realtime(false), m_priority(0)
44    , m_Thread ( NULL )
45 {}
46
47 IsoHandlerManager::IsoHandlerManager(Ieee1394Service& service, bool run_rt, int rt_prio)
48    : m_State(E_Created)
49    , m_service( service )
50    , m_realtime(run_rt), m_priority(rt_prio)
51    , m_Thread ( NULL )
52 {}
53
54 IsoHandlerManager::~IsoHandlerManager()
55 {
56     stopHandlers();
57     pruneHandlers();
58     if(m_IsoHandlers.size() > 0) {
59         debugError("Still some handlers in use\n");
60     }
61     if (m_Thread) {
62         m_Thread->Stop();
63         delete m_Thread;
64     }
65 }
66
67 bool
68 IsoHandlerManager::setThreadParameters(bool rt, int priority) {
69     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) switch to: (rt=%d, prio=%d)...\n", this, rt, priority);
70     if (priority > THREAD_MAX_RTPRIO) priority = THREAD_MAX_RTPRIO; // cap the priority
71     m_realtime = rt;
72     m_priority = priority;
73     bool result = true;
74     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
75         it != m_IsoHandlers.end();
76         ++it )
77     {
78         result &= (*it)->setThreadParameters(m_realtime, m_priority);
79     }
80
81     if (m_Thread) {
82         if (m_realtime) {
83             m_Thread->AcquireRealTime(m_priority);
84         } else {
85             m_Thread->DropRealTime();
86         }
87     }
88
89     return result;
90 }
91
92 /**
93  * Update the shadow variables. Should only be called from
94  * the iso handler iteration thread
95  */
96 void
97 IsoHandlerManager::updateShadowVars()
98 {
99     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "updating shadow vars...\n");
100     unsigned int i, cnt, max;
101     max = m_IsoHandlers.size();
102     for (i = 0, cnt = 0; i < max; i++) {
103         IsoHandler *h = m_IsoHandlers.at(i);
104         assert(h);
105         if (h->isEnabled()) {
106             // receive handlers are always poll'ed
107             // transmit handlers only when the client is ready
108             if (h->tryWaitForClient()) {
109                 m_IsoHandler_map_shadow[cnt] = h;
110                 m_poll_fds_shadow[cnt].fd = h->getFileDescriptor();
111                 m_poll_fds_shadow[cnt].revents = 0;
112                 m_poll_fds_shadow[cnt].events = POLLIN;
113                 cnt++;
114             } else {
115                 debugOutput(DEBUG_LEVEL_VERBOSE, "skipped handler %p\n", h);
116             }
117         }
118         if(cnt > ISOHANDLERMANAGER_MAX_ISO_HANDLERS_PER_PORT) {
119             debugWarning("Too much ISO Handlers in manager...\n");
120             break;
121         }
122     }
123     m_poll_nfds_shadow = cnt;
124     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, " updated shadow vars...\n");
125 }
126
127 bool
128 IsoHandlerManager::Init() {
129     debugOutput( DEBUG_LEVEL_VERBOSE, "%p: Init thread...\n", this);
130     bool result = true;
131     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
132         it != m_IsoHandlers.end();
133         ++it )
134     {
135         result &= (*it)->Init();
136     }
137     return result;
138 }
139
140 bool
141 IsoHandlerManager::Execute() {
142     int err;
143     unsigned int i;
144
145     unsigned int m_poll_timeout = 100;
146
147     updateShadowVars();
148     // bypass if no handlers are registered
149     if (m_poll_nfds_shadow == 0) {
150         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "bypass iterate since no handlers to poll\n");
151         usleep(m_poll_timeout * 1000);
152         return true;
153     }
154
155     // Use a shadow map of the fd's such that the poll call is not in a critical section
156     DEBUG_EXTREME( uint64_t poll_enter = m_service.getCurrentTimeAsUsecs() );
157     err = poll (m_poll_fds_shadow, m_poll_nfds_shadow, m_poll_timeout);
158     DEBUG_EXTREME( uint64_t poll_exit = m_service.getCurrentTimeAsUsecs() );
159
160     if (err == -1) {
161         if (errno == EINTR) {
162             return true;
163         }
164         debugFatal("poll error: %s\n", strerror (errno));
165         return false;
166     }
167
168     int nb_rcv = 0;
169     int nb_xmit = 0;
170     DEBUG_EXTREME( uint64_t iter_enter = m_service.getCurrentTimeAsUsecs() );
171     for (i = 0; i < m_poll_nfds_shadow; i++) {
172         if(m_poll_fds_shadow[i].revents) {
173             debugOutput(DEBUG_LEVEL_VERY_VERBOSE,
174                         "received events: %08X for (%d/%d, %p, %s)\n",
175                         m_poll_fds_shadow[i].revents,
176                         i, m_poll_nfds_shadow,
177                         m_IsoHandler_map_shadow[i],
178                         m_IsoHandler_map_shadow[i]->getTypeString());
179         }
180         if (m_poll_fds_shadow[i].revents & POLLERR) {
181             debugWarning("error on fd for %d\n",i);
182         }
183
184         if (m_poll_fds_shadow[i].revents & POLLHUP) {
185             debugWarning("hangup on fd for %d\n",i);
186         }
187
188         if(m_poll_fds_shadow[i].revents & (POLLIN)) {
189             if (m_IsoHandler_map_shadow[i]->getType() == IsoHandler::eHT_Receive) {
190                 m_IsoHandler_map_shadow[i]->iterate();
191                 nb_rcv++;
192             } else {
193                 // only iterate the xmit handler if it makes sense
194                 if(m_IsoHandler_map_shadow[i]->tryWaitForClient()) {
195                     m_IsoHandler_map_shadow[i]->iterate();
196                     nb_xmit++;
197                 }
198             }
199         }
200
201         #ifdef DEBUG
202         // check if the handler is still alive
203         if(m_IsoHandler_map_shadow[i]->isDead()) {
204             debugError("Iso handler (%p, %s) is dead!\n",
205                        m_IsoHandler_map_shadow[i],
206                        m_IsoHandler_map_shadow[i]->getTypeString());
207             return false; // shutdown the system
208         }
209         #endif
210        
211     }
212     DEBUG_EXTREME( uint64_t iter_exit = m_service.getCurrentTimeAsUsecs() );
213
214     debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, " poll took %6lldus, iterate took %6lldus, iterated (R: %2d, X: %2d) handlers\n",
215                        poll_exit-poll_enter, iter_exit-iter_enter,
216                        nb_rcv, nb_xmit);
217
218     return true;
219 }
220
221 bool IsoHandlerManager::init()
222 {
223     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing ISO manager %p...\n", this);
224     // check state
225     if(m_State != E_Created) {
226         debugError("Manager already initialized...\n");
227         return false;
228     }
229
230 #if ISOHANDLER_PER_HANDLER_THREAD
231     // the IsoHandlers will create their own thread.
232 #else
233     // create a thread to iterate our handlers
234     debugOutput( DEBUG_LEVEL_VERBOSE, "Start thread for %p...\n", this);
235     m_Thread = new Util::PosixThread(this, m_realtime, m_priority,
236                                      PTHREAD_CANCEL_DEFERRED);
237     if(!m_Thread) {
238         debugFatal("No thread\n");
239         return false;
240     }
241     if (m_Thread->Start() != 0) {
242         debugFatal("Could not start update thread\n");
243         return false;
244     }
245 #endif
246
247     m_State=E_Running;
248     return true;
249 }
250
251 bool
252 IsoHandlerManager::disable(IsoHandler *h) {
253     bool result;
254     int i=0;
255     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Disable on IsoHandler %p\n", h);
256     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
257         it != m_IsoHandlers.end();
258         ++it )
259     {
260         if ((*it) == h) {
261             result = h->disable();
262             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " disabled\n");
263             return result;
264         }
265         i++;
266     }
267     debugError("Handler not found\n");
268     return false;
269 }
270
271 bool
272 IsoHandlerManager::enable(IsoHandler *h) {
273     bool result;
274     int i=0;
275     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Enable on IsoHandler %p\n", h);
276     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
277         it != m_IsoHandlers.end();
278         ++it )
279     {
280         if ((*it) == h) {
281             result = h->enable();
282             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " enabled\n");
283             return result;
284         }
285         i++;
286     }
287     debugError("Handler not found\n");
288     return false;
289 }
290
291 bool IsoHandlerManager::registerHandler(IsoHandler *handler)
292 {
293     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
294     assert(handler);
295     handler->setVerboseLevel(getDebugLevel());
296     m_IsoHandlers.push_back(handler);
297     updateShadowVars();
298     return true;
299 }
300
301 bool IsoHandlerManager::unregisterHandler(IsoHandler *handler)
302 {
303     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
304     assert(handler);
305
306     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
307       it != m_IsoHandlers.end();
308       ++it )
309     {
310         if ( *it == handler ) {
311             m_IsoHandlers.erase(it);
312             updateShadowVars();
313             return true;
314         }
315     }
316     debugFatal("Could not find handler (%p)\n", handler);
317     return false; //not found
318 }
319
320 /**
321  * Registers an StreamProcessor with the IsoHandlerManager.
322  *
323  * If nescessary, an IsoHandler is created to handle this stream.
324  * Once an StreamProcessor is registered to the handler, it will be included
325  * in the ISO streaming cycle (i.e. receive/transmit of it will occur).
326  *
327  * @param stream the stream to register
328  * @return true if registration succeeds
329  *
330  * \todo : currently there is a one-to-one mapping
331  *        between streams and handlers, this is not ok for
332  *        multichannel receive
333  */
334 bool IsoHandlerManager::registerStream(StreamProcessor *stream)
335 {
336     debugOutput( DEBUG_LEVEL_VERBOSE, "Registering stream %p\n",stream);
337     assert(stream);
338
339     IsoHandler* h = NULL;
340
341     // make sure the stream isn't already attached to a handler
342     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
343       it != m_IsoHandlers.end();
344       ++it )
345     {
346         if((*it)->isStreamRegistered(stream)) {
347             debugError( "stream already registered!\n");
348             return false;
349         }
350     }
351
352     // clean up all handlers that aren't used
353     pruneHandlers();
354
355     // allocate a handler for this stream
356     if (stream->getType()==StreamProcessor::ePT_Receive) {
357         // setup the optimal parameters for the raw1394 ISO buffering
358         unsigned int packets_per_period = stream->getPacketsPerPeriod();
359         unsigned int max_packet_size = stream->getMaxPacketSize();
360         unsigned int page_size = getpagesize() - 2; // for one reason or another this is necessary
361
362         // Ensure we don't request a packet size bigger than the
363         // kernel-enforced maximum which is currently 1 page.
364         if (max_packet_size > page_size) {
365             debugError("max packet size (%u) > page size (%u)\n", max_packet_size, page_size);
366             return false;
367         }
368
369         unsigned int irq_interval = packets_per_period / MINIMUM_INTERRUPTS_PER_PERIOD;
370         if(irq_interval <= 0) irq_interval=1;
371        
372         // the receive buffer size doesn't matter for the latency,
373         // but it has a minimal value in order for libraw to operate correctly (300)
374         int buffers=400;
375
376         // create the actual handler
377         h = new IsoHandler(*this, IsoHandler::eHT_Receive,
378                            buffers, max_packet_size, irq_interval);
379
380         debugOutput( DEBUG_LEVEL_VERBOSE, " creating IsoRecvHandler\n");
381
382         if(!h) {
383             debugFatal("Could not create IsoRecvHandler\n");
384             return false;
385         }
386
387     } else if (stream->getType()==StreamProcessor::ePT_Transmit) {
388         // setup the optimal parameters for the raw1394 ISO buffering
389         unsigned int packets_per_period = stream->getPacketsPerPeriod();
390         unsigned int max_packet_size = stream->getMaxPacketSize();
391 //         unsigned int page_size = getpagesize();
392
393         // Ensure we don't request a packet size bigger than the
394         // kernel-enforced maximum which is currently 1 page.
395 //         if (max_packet_size > page_size) {
396 //             debugError("max packet size (%u) > page size (%u)\n", max_packet_size, page_size);
397 //             return false;
398 //         }
399         if (max_packet_size > MAX_XMIT_PACKET_SIZE) {
400             debugError("max packet size (%u) > MAX_XMIT_PACKET_SIZE (%u)\n",
401                        max_packet_size, MAX_XMIT_PACKET_SIZE);
402             return false;
403         }
404
405         // the SP specifies how many packets to ISO-buffer
406         int buffers = stream->getNbPacketsIsoXmitBuffer();
407         if (buffers > MAX_XMIT_NB_BUFFERS) {
408             debugOutput(DEBUG_LEVEL_VERBOSE,
409                         "nb buffers (%u) > MAX_XMIT_NB_BUFFERS (%u)\n",
410                         buffers, MAX_XMIT_NB_BUFFERS);
411             buffers = MAX_XMIT_NB_BUFFERS;
412         }
413         unsigned int irq_interval = buffers / MINIMUM_INTERRUPTS_PER_PERIOD;
414         if(irq_interval <= 0) irq_interval=1;
415
416         debugOutput( DEBUG_LEVEL_VERBOSE, " creating IsoXmitHandler\n");
417
418         // create the actual handler
419         h = new IsoHandler(*this, IsoHandler::eHT_Transmit,
420                            buffers, max_packet_size, irq_interval);
421
422         if(!h) {
423             debugFatal("Could not create IsoXmitHandler\n");
424             return false;
425         }
426
427     } else {
428         debugFatal("Bad stream type\n");
429         return false;
430     }
431
432     h->setVerboseLevel(getDebugLevel());
433
434     // init the handler
435     if(!h->init()) {
436         debugFatal("Could not initialize receive handler\n");
437         return false;
438     }
439
440     // set the handler's thread parameters
441     // receive handlers have lower priority than the client thread
442     // since they have ISO side buffering
443     // xmit handlers have higher priority since we want client side
444     // frames to be put into the ISO buffers ASAP
445     int thread_prio;
446     if (stream->getType()==StreamProcessor::ePT_Receive) {
447         thread_prio = m_priority - 1;
448         if (thread_prio < THREAD_MIN_RTPRIO) thread_prio = THREAD_MIN_RTPRIO;
449     } else {
450         thread_prio = m_priority + 1;
451         if (thread_prio > THREAD_MAX_RTPRIO) thread_prio = THREAD_MAX_RTPRIO;
452     }
453
454     if(!h->setThreadParameters(m_realtime, thread_prio)) {
455         debugFatal("Could not set handler thread parameters\n");
456         return false;
457     }
458
459     // register the stream with the handler
460     if(!h->registerStream(stream)) {
461         debugFatal("Could not register receive stream with handler\n");
462         return false;
463     }
464
465     // register the handler with the manager
466     if(!registerHandler(h)) {
467         debugFatal("Could not register receive handler with manager\n");
468         return false;
469     }
470     debugOutput( DEBUG_LEVEL_VERBOSE, " registered stream (%p) with handler (%p)\n", stream, h);
471
472     m_StreamProcessors.push_back(stream);
473     debugOutput( DEBUG_LEVEL_VERBOSE, " %d streams, %d handlers registered\n",
474                                       m_StreamProcessors.size(), m_IsoHandlers.size());
475     return true;
476 }
477
478 bool IsoHandlerManager::unregisterStream(StreamProcessor *stream)
479 {
480     debugOutput( DEBUG_LEVEL_VERBOSE, "Unregistering stream %p\n",stream);
481     assert(stream);
482
483     // make sure the stream isn't attached to a handler anymore
484     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
485       it != m_IsoHandlers.end();
486       ++it )
487     {
488         if((*it)->isStreamRegistered(stream)) {
489             if(!(*it)->unregisterStream(stream)) {
490                 debugOutput( DEBUG_LEVEL_VERBOSE, " could not unregister stream (%p) from handler (%p)...\n",stream,*it);
491                 return false;
492             }
493             debugOutput( DEBUG_LEVEL_VERBOSE, " unregistered stream (%p) from handler (%p)...\n",stream,*it);
494         }
495     }
496
497     // clean up all handlers that aren't used
498     pruneHandlers();
499
500     // remove the stream from the registered streams list
501     for ( StreamProcessorVectorIterator it = m_StreamProcessors.begin();
502       it != m_StreamProcessors.end();
503       ++it )
504     {
505         if ( *it == stream ) {
506             m_StreamProcessors.erase(it);
507             debugOutput( DEBUG_LEVEL_VERBOSE, " deleted stream (%p) from list...\n", *it);
508             return true;
509         }
510     }
511     return false; //not found
512 }
513
514 /**
515  * @brief unregister a handler from the manager
516  * @note called without the lock held.
517  */
518 void IsoHandlerManager::pruneHandlers() {
519     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
520     IsoHandlerVector toUnregister;
521
522     // find all handlers that are not in use
523     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
524           it != m_IsoHandlers.end();
525           ++it )
526     {
527         if(!((*it)->inUse())) {
528             debugOutput( DEBUG_LEVEL_VERBOSE, " handler (%p) not in use\n",*it);
529             toUnregister.push_back(*it);
530         }
531     }
532     // delete them
533     for ( IsoHandlerVectorIterator it = toUnregister.begin();
534           it != toUnregister.end();
535           ++it )
536     {
537         unregisterHandler(*it);
538
539         debugOutput( DEBUG_LEVEL_VERBOSE, " deleting handler (%p)\n",*it);
540
541         // Now the handler's been unregistered it won't be reused
542         // again.  Therefore it really needs to be formally deleted
543         // to free up the raw1394 handle.  Otherwise things fall
544         // apart after several xrun recoveries as the system runs
545         // out of resources to support all the disused but still
546         // allocated raw1394 handles.  At least this is the current
547         // theory as to why we end up with "memory allocation"
548         // failures after several Xrun recoveries.
549         delete *it;
550     }
551 }
552
553 bool
554 IsoHandlerManager::stopHandlerForStream(Streaming::StreamProcessor *stream) {
555     // check state
556     if(m_State != E_Running) {
557         debugError("Incorrect state, expected E_Running, got %s\n", eHSToString(m_State));
558         return false;
559     }
560     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
561       it != m_IsoHandlers.end();
562       ++it )
563     {
564         if((*it)->isStreamRegistered(stream)) {
565             bool result;
566             debugOutput( DEBUG_LEVEL_VERBOSE, " stopping handler %p for stream %p\n", *it, stream);
567             result = (*it)->disable();
568             if(!result) {
569                 debugOutput( DEBUG_LEVEL_VERBOSE, " could not disable handler (%p)\n",*it);
570                 return false;
571             }
572             return true;
573         }
574     }
575     debugError("Stream %p has no attached handler\n", stream);
576     return false;
577 }
578
579 int
580 IsoHandlerManager::getPacketLatencyForStream(Streaming::StreamProcessor *stream) {
581     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
582       it != m_IsoHandlers.end();
583       ++it )
584     {
585         if((*it)->isStreamRegistered(stream)) {
586             return (*it)->getPacketLatency();
587         }
588     }
589     debugError("Stream %p has no attached handler\n", stream);
590     return 0;
591 }
592
593 void
594 IsoHandlerManager::flushHandlerForStream(Streaming::StreamProcessor *stream) {
595     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
596       it != m_IsoHandlers.end();
597       ++it )
598     {
599         if((*it)->isStreamRegistered(stream)) {
600             return (*it)->flush();
601         }
602     }
603     debugError("Stream %p has no attached handler\n", stream);
604     return;
605 }
606
607 bool
608 IsoHandlerManager::startHandlerForStream(Streaming::StreamProcessor *stream) {
609     return startHandlerForStream(stream, -1);
610 }
611
612 bool
613 IsoHandlerManager::startHandlerForStream(Streaming::StreamProcessor *stream, int cycle) {
614     // check state
615     if(m_State != E_Running) {
616         debugError("Incorrect state, expected E_Running, got %s\n", eHSToString(m_State));
617         return false;
618     }
619     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
620       it != m_IsoHandlers.end();
621       ++it )
622     {
623         if((*it)->isStreamRegistered(stream)) {
624             bool result;
625             debugOutput( DEBUG_LEVEL_VERBOSE, " starting handler %p for stream %p\n", *it, stream);
626             result = (*it)->enable(cycle);
627             if(!result) {
628                 debugOutput( DEBUG_LEVEL_VERBOSE, " could not enable handler (%p)\n",*it);
629                 return false;
630             }
631             return true;
632         }
633     }
634     debugError("Stream %p has no attached handler\n", stream);
635     return false;
636 }
637
638 bool IsoHandlerManager::stopHandlers() {
639     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
640
641     // check state
642     if(m_State != E_Running) {
643         debugError("Incorrect state, expected E_Running, got %s\n", eHSToString(m_State));
644         return false;
645     }
646
647     bool retval=true;
648
649     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
650         it != m_IsoHandlers.end();
651         ++it )
652     {
653         debugOutput( DEBUG_LEVEL_VERBOSE, "Stopping handler (%p)\n",*it);
654         if(!(*it)->disable()){
655             debugOutput( DEBUG_LEVEL_VERBOSE, " could not stop handler (%p)\n",*it);
656             retval=false;
657         }
658     }
659
660     if (retval) {
661         m_State=E_Prepared;
662     } else {
663         m_State=E_Error;
664     }
665     return retval;
666 }
667
668 bool IsoHandlerManager::reset() {
669     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
670     // check state
671     if(m_State == E_Error) {
672         debugFatal("Resetting from error condition not yet supported...\n");
673         return false;
674     }
675     // if not in an error condition, reset means stop the handlers
676     return stopHandlers();
677 }
678
679 void IsoHandlerManager::setVerboseLevel(int i) {
680     setDebugLevel(i);
681     // propagate the debug level
682     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
683           it != m_IsoHandlers.end();
684           ++it )
685     {
686         (*it)->setVerboseLevel(i);
687     }
688 }
689
690 void IsoHandlerManager::dumpInfo() {
691     int i=0;
692     debugOutputShort( DEBUG_LEVEL_NORMAL, "Dumping IsoHandlerManager Stream handler information...\n");
693     debugOutputShort( DEBUG_LEVEL_NORMAL, " State: %d\n",(int)m_State);
694
695     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
696           it != m_IsoHandlers.end();
697           ++it )
698     {
699         debugOutputShort( DEBUG_LEVEL_NORMAL, " IsoHandler %d (%p)\n",i++,*it);
700         (*it)->dumpInfo();
701     }
702 }
703
704 const char *
705 IsoHandlerManager::eHSToString(enum eHandlerStates s) {
706     switch (s) {
707         default: return "Invalid";
708         case E_Created: return "Created";
709         case E_Prepared: return "Prepared";
710         case E_Running: return "Running";
711         case E_Error: return "Error";
712     }
713 }
Note: See TracBrowser for help on using the browser.