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

Revision 782, 22.6 kB (checked in by ppalmers, 16 years ago)

fix mutex macro's; don't run thread in old_style mode

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