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

Revision 784, 22.7 kB (checked in by ppalmers, 13 years ago)

fix shutdown bug

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