root/trunk/libffado/src/libstreaming/util/IsoHandlerManager.cpp

Revision 739, 22.1 kB (checked in by ppalmers, 13 years ago)

- Adapt the ffado external API (upgrade to v3)

NEEDS NEW JACK BACKEND

- simplify FFADODevice constructor even more
- implement first framework support for supporting multiple adapters.

currently all firewire adapters are scanned for supported devices unless specified otherwise
however attaching devices to separate adapters is not supported. using multiple adapters at
that are connected together might work.

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 library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License version 2.1, as published by the Free Software Foundation;
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21  * MA 02110-1301 USA
22  */
23
24 #include "IsoHandlerManager.h"
25 #include "IsoHandler.h"
26 #include "../generic/IsoStream.h"
27
28 #include "libutil/PosixThread.h"
29
30 #include <assert.h>
31
32 #define MINIMUM_INTERRUPTS_PER_PERIOD  4U
33 #define PACKETS_PER_INTERRUPT          4U
34
35 namespace Streaming
36 {
37
38 IMPL_DEBUG_MODULE( IsoHandlerManager, IsoHandlerManager, DEBUG_LEVEL_NORMAL );
39
40 IsoHandlerManager::IsoHandlerManager() :
41    m_State(E_Created),
42    m_poll_timeout(100), m_poll_fds(0), m_poll_nfds(0),
43    m_realtime(false), m_priority(0), m_xmit_nb_frames( 20 )
44 {}
45
46 IsoHandlerManager::IsoHandlerManager(bool run_rt, unsigned int rt_prio) :
47    m_State(E_Created),
48    m_poll_timeout(100), m_poll_fds(0), m_poll_nfds(0),
49    m_realtime(run_rt), m_priority(rt_prio), m_xmit_nb_frames( 20 )
50 {}
51
52 bool IsoHandlerManager::init()
53 {
54     // the tread that performs the actual packet transfer
55     // needs high priority
56     unsigned int prio=m_priority+6;
57
58     if (prio>98) prio=98;
59
60     m_isoManagerThread=new Util::PosixThread(
61         this,
62         m_realtime, prio,
63         PTHREAD_CANCEL_DEFERRED);
64
65     if(!m_isoManagerThread) {
66         debugFatal("Could not create iso manager thread\n");
67         return false;
68     }
69
70     // propagate the debug level
71     m_isoManagerThread->setVerboseLevel(getDebugLevel());
72
73     return true;
74 }
75
76 bool IsoHandlerManager::Init()
77 {
78     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
79     pthread_mutex_init(&m_debug_lock, NULL);
80
81     return true;
82 }
83
84 /**
85  * the IsoHandlerManager thread execute function iterates the handlers.
86  *
87  * This means that once the thread is running, streams are
88  * transmitted and received (if present on the bus). Make sure
89  * that the clients are registered & ready before starting the
90  * thread!
91  *
92  * The register and unregister functions are thread unsafe, so
93  * should not be used when the thread is running.
94  *
95  * @return false if the handlers could not be iterated.
96  */
97 bool IsoHandlerManager::Execute()
98 {
99 //     updateCycleTimers();
100
101     pthread_mutex_lock(&m_debug_lock);
102
103     if(!iterate()) {
104         debugFatal("Could not iterate the isoManager\n");
105         pthread_mutex_unlock(&m_debug_lock);
106         return false;
107     }
108
109     pthread_mutex_unlock(&m_debug_lock);
110
111     return true;
112 }
113
114 /**
115  * Poll the handlers managed by this manager, and iterate them
116  * when ready
117  *
118  * @return true when successful
119  */
120 bool IsoHandlerManager::iterate()
121 {
122     int err;
123     int i=0;
124     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "poll %d fd's, timeout = %dms...\n", m_poll_nfds, m_poll_timeout);
125
126     err = poll (m_poll_fds, m_poll_nfds, m_poll_timeout);
127
128     if (err == -1) {
129         if (errno == EINTR) {
130             return true;
131         }
132         debugFatal("poll error: %s\n", strerror (errno));
133         return false;
134     }
135
136 //     #ifdef DEBUG
137 //     for (i = 0; i < m_poll_nfds; i++) {
138 //         IsoHandler *s = m_IsoHandlers.at(i);
139 //         assert(s);
140 //         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%d) handler %p: iterate? %d, revents: %08X\n",
141 //             i, s, (m_poll_fds[i].revents & (POLLIN) == 1), m_poll_fds[i].revents);
142 //     }
143 //     #endif
144
145     for (i = 0; i < m_poll_nfds; i++) {
146         if (m_poll_fds[i].revents & POLLERR) {
147             debugWarning("error on fd for %d\n",i);
148         }
149
150         if (m_poll_fds[i].revents & POLLHUP) {
151             debugWarning("hangup on fd for %d\n",i);
152         }
153
154         if(m_poll_fds[i].revents & (POLLIN)) {
155             IsoHandler *s = m_IsoHandlers.at(i);
156             assert(s);
157             s->iterate();
158         }
159     }
160
161     return true;
162
163 }
164
165 bool IsoHandlerManager::registerHandler(IsoHandler *handler)
166 {
167     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
168     assert(handler);
169
170     m_IsoHandlers.push_back(handler);
171
172     handler->setVerboseLevel(getDebugLevel());
173
174     // rebuild the fd map for poll()'ing.
175     return rebuildFdMap();
176
177 }
178
179 bool IsoHandlerManager::unregisterHandler(IsoHandler *handler)
180 {
181     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
182     assert(handler);
183
184     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
185       it != m_IsoHandlers.end();
186       ++it )
187     {
188         if ( *it == handler ) {
189             // erase the iso handler from the list
190             m_IsoHandlers.erase(it);
191             // rebuild the fd map for poll()'ing.
192             return rebuildFdMap();
193         }
194     }
195     debugFatal("Could not find handler (%p)\n", handler);
196
197     return false; //not found
198
199 }
200
201 bool IsoHandlerManager::rebuildFdMap() {
202     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
203     int i=0;
204
205     m_poll_nfds=0;
206     if(m_poll_fds) free(m_poll_fds);
207
208     // count the number of handlers
209     m_poll_nfds=m_IsoHandlers.size();
210
211     // allocate the fd array
212     m_poll_fds   = (struct pollfd *) calloc (m_poll_nfds, sizeof (struct pollfd));
213     if(!m_poll_fds) {
214         debugFatal("Could not allocate memory for poll FD array\n");
215         return false;
216     }
217
218     // fill the fd map
219     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
220       it != m_IsoHandlers.end();
221       ++it )
222     {
223         m_poll_fds[i].fd=(*it)->getFileDescriptor();
224         m_poll_fds[i].events = POLLIN;
225         i++;
226     }
227
228     return true;
229 }
230
231 void IsoHandlerManager::disablePolling(IsoStream *stream) {
232     int i=0;
233
234     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Disable polling on stream %p\n",stream);
235
236     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
237         it != m_IsoHandlers.end();
238         ++it )
239     {
240         if ((*it)->isStreamRegistered(stream)) {
241             m_poll_fds[i].events = 0;
242             m_poll_fds[i].revents = 0;
243             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "polling disabled\n");
244         }
245
246         i++;
247     }
248 }
249
250 void IsoHandlerManager::enablePolling(IsoStream *stream) {
251     int i=0;
252
253     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Enable polling on stream %p\n",stream);
254
255     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
256         it != m_IsoHandlers.end();
257         ++it )
258     {
259         if ((*it)->isStreamRegistered(stream)) {
260             m_poll_fds[i].events = POLLIN;
261             m_poll_fds[i].revents = 0;
262             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "polling enabled\n");
263         }
264
265         i++;
266     }
267 }
268
269
270 /**
271  * Registers an IsoStream with the IsoHandlerManager.
272  *
273  * If nescessary, an IsoHandler is created to handle this stream.
274  * Once an IsoStream is registered to the handler, it will be included
275  * in the ISO streaming cycle (i.e. receive/transmit of it will occur).
276  *
277  * @param stream the stream to register
278  * @return true if registration succeeds
279  *
280  * \todo : currently there is a one-to-one mapping
281  *        between streams and handlers, this is not ok for
282  *        multichannel receive
283  */
284 bool IsoHandlerManager::registerStream(IsoStream *stream)
285 {
286     debugOutput( DEBUG_LEVEL_VERBOSE, "Registering stream %p\n",stream);
287     assert(stream);
288
289     // make sure the stream isn't already attached to a handler
290     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
291       it != m_IsoHandlers.end();
292       ++it )
293     {
294         if((*it)->isStreamRegistered(stream)) {
295             debugWarning( "stream already registered!\n");
296             (*it)->unregisterStream(stream);
297
298         }
299     }
300
301     // clean up all handlers that aren't used
302     pruneHandlers();
303
304     // allocate a handler for this stream
305     if (stream->getStreamType()==IsoStream::eST_Receive) {
306         // setup the optimal parameters for the raw1394 ISO buffering
307         unsigned int packets_per_period = stream->getPacketsPerPeriod();
308
309 #if 1
310         // hardware interrupts occur when one DMA block is full, and the size of one DMA
311         // block = PAGE_SIZE. Setting the max_packet_size makes sure that the HW irq
312         // occurs at a period boundary (optimal CPU use)
313
314         // NOTE: try and use MINIMUM_INTERRUPTS_PER_PERIOD hardware interrupts
315         //       per period for better latency.
316         unsigned int max_packet_size=(MINIMUM_INTERRUPTS_PER_PERIOD * getpagesize()) / packets_per_period;
317         if (max_packet_size < stream->getMaxPacketSize()) {
318             debugWarning("calculated max packet size (%u) < stream max packet size (%u)\n",
319                          max_packet_size ,(unsigned int)stream->getMaxPacketSize());
320             max_packet_size = stream->getMaxPacketSize();
321         }
322
323         // Ensure we don't request a packet size bigger than the
324         // kernel-enforced maximum which is currently 1 page.
325         if (max_packet_size > (unsigned int)getpagesize()) {
326             debugWarning("max packet size (%u) > page size (%u)\n", max_packet_size ,(unsigned int)getpagesize());
327             max_packet_size = getpagesize();
328         }
329
330         unsigned int irq_interval = packets_per_period / MINIMUM_INTERRUPTS_PER_PERIOD;
331         if(irq_interval <= 0) irq_interval=1;
332         // FIXME: test
333         //irq_interval=1;
334
335 #else
336         // hardware interrupts occur when one DMA block is full, and the size of one DMA
337         // block = PAGE_SIZE. Setting the max_packet_size enables control over the IRQ
338         // frequency, as the controller uses max_packet_size, and not the effective size
339         // when writing to the DMA buffer.
340
341         // configure it such that we have an irq for every PACKETS_PER_INTERRUPT packets
342         unsigned int irq_interval=PACKETS_PER_INTERRUPT;
343
344         // unless the period size doesn't allow this
345         if ((packets_per_period/MINIMUM_INTERRUPTS_PER_PERIOD) < irq_interval) {
346             irq_interval=1;
347         }
348
349         // FIXME: test
350         irq_interval=1;
351 #warning Using fixed irq_interval
352
353         unsigned int max_packet_size=getpagesize() / irq_interval;
354
355         if (max_packet_size < stream->getMaxPacketSize()) {
356             max_packet_size=stream->getMaxPacketSize();
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 > (unsigned int)getpagesize())
362                     max_packet_size = getpagesize();
363
364 #endif
365         /* the receive buffer size doesn't matter for the latency,
366            but it has a minimal value in order for libraw to operate correctly (300) */
367         int buffers=400;
368
369         // create the actual handler
370         IsoRecvHandler *h = new IsoRecvHandler(stream->getPort(), buffers,
371                                                max_packet_size, irq_interval);
372
373         debugOutput( DEBUG_LEVEL_VERBOSE, " registering IsoRecvHandler\n");
374
375         if(!h) {
376             debugFatal("Could not create IsoRecvHandler\n");
377             return false;
378         }
379
380         h->setVerboseLevel(getDebugLevel());
381
382         // init the handler
383         if(!h->init()) {
384             debugFatal("Could not initialize receive handler\n");
385             return false;
386         }
387
388         // register the stream with the handler
389         if(!h->registerStream(stream)) {
390             debugFatal("Could not register receive stream with handler\n");
391             return false;
392         }
393
394         // register the handler with the manager
395         if(!registerHandler(h)) {
396             debugFatal("Could not register receive handler with manager\n");
397             return false;
398         }
399         debugOutput( DEBUG_LEVEL_VERBOSE, " registered stream (%p) with handler (%p)\n",stream,h);
400     }
401
402     if (stream->getStreamType()==IsoStream::eST_Transmit) {
403         // setup the optimal parameters for the raw1394 ISO buffering
404         unsigned int packets_per_period = stream->getPacketsPerPeriod();
405
406 #if 1
407         // hardware interrupts occur when one DMA block is full, and the size of one DMA
408         // block = PAGE_SIZE. Setting the max_packet_size makes sure that the HW irq
409         // occurs at a period boundary (optimal CPU use)
410         // NOTE: try and use MINIMUM_INTERRUPTS_PER_PERIOD interrupts per period
411         //       for better latency.
412         unsigned int max_packet_size=MINIMUM_INTERRUPTS_PER_PERIOD * getpagesize() / packets_per_period;
413         if (max_packet_size < stream->getMaxPacketSize()) {
414             max_packet_size = stream->getMaxPacketSize();
415         }
416
417         // Ensure we don't request a packet size bigger than the
418         // kernel-enforced maximum which is currently 1 page.
419         if (max_packet_size > (unsigned int)getpagesize())
420                     max_packet_size = getpagesize();
421
422          unsigned int irq_interval = packets_per_period / MINIMUM_INTERRUPTS_PER_PERIOD;
423          if(irq_interval <= 0) irq_interval=1;
424 #else
425         // hardware interrupts occur when one DMA block is full, and the size of one DMA
426         // block = PAGE_SIZE. Setting the max_packet_size enables control over the IRQ
427         // frequency, as the controller uses max_packet_size, and not the effective size
428         // when writing to the DMA buffer.
429
430         // configure it such that we have an irq for every PACKETS_PER_INTERRUPT packets
431         unsigned int irq_interval = PACKETS_PER_INTERRUPT;
432
433         // unless the period size doesn't allow this
434         if ((packets_per_period/MINIMUM_INTERRUPTS_PER_PERIOD) < irq_interval) {
435             irq_interval = 1;
436         }
437
438         // FIXME: test
439         irq_interval = 1;
440 #warning Using fixed irq_interval
441
442         unsigned int max_packet_size = getpagesize() / irq_interval;
443
444         if (max_packet_size < stream->getMaxPacketSize()) {
445             max_packet_size = stream->getMaxPacketSize();
446         }
447
448         // Ensure we don't request a packet size bigger than the
449         // kernel-enforced maximum which is currently 1 page.
450         if (max_packet_size > (unsigned int)getpagesize())
451                     max_packet_size = getpagesize();
452 #endif
453         // the transmit buffer size should be as low as possible for latency.
454         // note however that the raw1394 subsystem tries to keep this buffer
455         // full, so we have to make sure that we have enough events in our
456         // event buffers
457
458         // FIXME: latency spoiler
459         // every irq_interval packets an interrupt will occur. that is when
460         // buffers get transfered, meaning that we should have at least some
461         // margin here
462 //         int buffers=irq_interval * 2;
463
464         // the SPM specifies how many packets to buffer
465         int buffers = stream->getNominalPacketsNeeded(m_xmit_nb_frames);
466
467         // create the actual handler
468         IsoXmitHandler *h = new IsoXmitHandler(stream->getPort(), buffers,
469                                                max_packet_size, irq_interval);
470
471         debugOutput( DEBUG_LEVEL_VERBOSE, " registering IsoXmitHandler\n");
472
473         if(!h) {
474             debugFatal("Could not create IsoXmitHandler\n");
475             return false;
476         }
477
478         h->setVerboseLevel(getDebugLevel());
479
480         // init the handler
481         if(!h->init()) {
482             debugFatal("Could not initialize transmit handler\n");
483             return false;
484         }
485
486         // register the stream with the handler
487         if(!h->registerStream(stream)) {
488             debugFatal("Could not register transmit stream with handler\n");
489             return false;
490         }
491
492         // register the handler with the manager
493         if(!registerHandler(h)) {
494             debugFatal("Could not register transmit handler with manager\n");
495             return false;
496         }
497         debugOutput( DEBUG_LEVEL_VERBOSE, " registered stream (%p) with handler (%p)\n",stream,h);
498     }
499
500     m_IsoStreams.push_back(stream);
501     debugOutput( DEBUG_LEVEL_VERBOSE, " %d streams, %d handlers registered\n",
502                                       m_IsoStreams.size(), m_IsoHandlers.size());
503
504     return true;
505 }
506
507 bool IsoHandlerManager::unregisterStream(IsoStream *stream)
508 {
509     debugOutput( DEBUG_LEVEL_VERBOSE, "Unregistering stream %p\n",stream);
510     assert(stream);
511
512     // make sure the stream isn't attached to a handler anymore
513     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
514       it != m_IsoHandlers.end();
515       ++it )
516     {
517         if((*it)->isStreamRegistered(stream)) {
518             if(!(*it)->unregisterStream(stream)) {
519                 debugOutput( DEBUG_LEVEL_VERBOSE, " could not unregister stream (%p) from handler (%p)...\n",stream,*it);
520                 return false;
521             }
522
523             debugOutput( DEBUG_LEVEL_VERBOSE, " unregistered stream (%p) from handler (%p)...\n",stream,*it);
524         }
525     }
526
527     // clean up all handlers that aren't used
528     pruneHandlers();
529
530     // remove the stream from the registered streams list
531     for ( IsoStreamVectorIterator it = m_IsoStreams.begin();
532       it != m_IsoStreams.end();
533       ++it )
534     {
535         if ( *it == stream ) {
536             m_IsoStreams.erase(it);
537
538             debugOutput( DEBUG_LEVEL_VERBOSE, " deleted stream (%p) from list...\n", *it);
539             return true;
540         }
541     }
542
543     return false; //not found
544
545 }
546
547 void IsoHandlerManager::pruneHandlers() {
548     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
549     IsoHandlerVector toUnregister;
550
551     // find all handlers that are not in use
552     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
553           it != m_IsoHandlers.end();
554           ++it )
555     {
556         if(!((*it)->inUse())) {
557             debugOutput( DEBUG_LEVEL_VERBOSE, " handler (%p) not in use\n",*it);
558             toUnregister.push_back(*it);
559         }
560     }
561     // delete them
562     for ( IsoHandlerVectorIterator it = toUnregister.begin();
563           it != toUnregister.end();
564           ++it )
565     {
566         unregisterHandler(*it);
567         debugOutput( DEBUG_LEVEL_VERBOSE, " deleting handler (%p)\n",*it);
568
569         // Now the handler's been unregistered it won't be reused
570         // again.  Therefore it really needs to be formally deleted
571         // to free up the raw1394 handle.  Otherwise things fall
572         // apart after several xrun recoveries as the system runs
573         // out of resources to support all the disused but still
574         // allocated raw1394 handles.  At least this is the current
575         // theory as to why we end up with "memory allocation"
576         // failures after several Xrun recoveries.
577         delete *it;
578     }
579
580 }
581
582
583 bool IsoHandlerManager::prepare()
584 {
585     bool retval=true;
586
587     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
588
589     // check state
590     if(m_State != E_Created) {
591         debugError("Incorrect state, expected E_Created, got %d\n",(int)m_State);
592         return false;
593     }
594
595     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
596           it != m_IsoHandlers.end();
597           ++it )
598     {
599         if(!(*it)->prepare()) {
600             debugFatal("Could not prepare handlers\n");
601             retval=false;
602         }
603     }
604
605     if (retval) {
606         m_State=E_Prepared;
607     } else {
608         m_State=E_Error;
609     }
610
611     return retval;
612 }
613
614 bool IsoHandlerManager::startHandlers() {
615     return startHandlers(-1);
616 }
617
618 bool IsoHandlerManager::startHandlers(int cycle) {
619     bool retval=true;
620
621     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
622
623     // check state
624     if(m_State != E_Prepared) {
625         debugError("Incorrect state, expected E_Prepared, got %d\n",(int)m_State);
626         return false;
627     }
628
629     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
630         it != m_IsoHandlers.end();
631         ++it )
632     {
633         debugOutput( DEBUG_LEVEL_VERBOSE, " starting handler (%p)\n",*it);
634         if(!(*it)->start(cycle)) {
635             debugOutput( DEBUG_LEVEL_VERBOSE, " could not start handler (%p)\n",*it);
636             retval=false;
637         }
638     }
639
640     debugOutput( DEBUG_LEVEL_VERBOSE, "Starting ISO iterator thread...\n");
641
642     // note: libraw1394 doesn't like it if you poll() and/or iterate() before
643     //       starting the streams.
644     // start the iso runner thread
645     m_isoManagerThread->Start();
646
647     if (retval) {
648         m_State=E_Running;
649     } else {
650         m_State=E_Error;
651     }
652
653     return retval;
654 }
655
656 bool IsoHandlerManager::stopHandlers() {
657     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
658
659     // check state
660     if(m_State != E_Running) {
661         debugError("Incorrect state, expected E_Running, got %d\n",(int)m_State);
662         return false;
663     }
664
665     bool retval=true;
666
667     debugOutput( DEBUG_LEVEL_VERBOSE, "Stopping ISO iterator thread...\n");
668     m_isoManagerThread->Stop();
669
670     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
671         it != m_IsoHandlers.end();
672         ++it )
673     {
674         debugOutput( DEBUG_LEVEL_VERBOSE, "Stopping handler (%p)\n",*it);
675         if(!(*it)->stop()){
676             debugOutput( DEBUG_LEVEL_VERBOSE, " could not stop handler (%p)\n",*it);
677             retval=false;
678         }
679     }
680
681     if (retval) {
682         m_State=E_Prepared;
683     } else {
684         m_State=E_Error;
685     }
686
687     return retval;
688 }
689
690 bool IsoHandlerManager::reset() {
691     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
692
693     // check state
694     if(m_State == E_Error) {
695         debugFatal("Resetting from error condition not yet supported...\n");
696         return false;
697     }
698
699     // if not in an error condition, reset means stop the handlers
700     return stopHandlers();
701 }
702
703
704 void IsoHandlerManager::setVerboseLevel(int i) {
705     setDebugLevel(i);
706
707     // propagate the debug level
708     if(m_isoManagerThread) {
709         m_isoManagerThread->setVerboseLevel(getDebugLevel());
710     }
711
712     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
713           it != m_IsoHandlers.end();
714           ++it )
715     {
716         (*it)->setVerboseLevel(i);
717     }
718 }
719
720 void IsoHandlerManager::dumpInfo() {
721     int i=0;
722
723     debugOutputShort( DEBUG_LEVEL_NORMAL, "Dumping IsoHandlerManager Stream handler information...\n");
724     debugOutputShort( DEBUG_LEVEL_NORMAL, " State: %d\n",(int)m_State);
725
726     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
727           it != m_IsoHandlers.end();
728           ++it )
729     {
730         debugOutputShort( DEBUG_LEVEL_NORMAL, " IsoHandler %d (%p)\n",i++,*it);
731
732         (*it)->dumpInfo();
733     }
734
735 }
736
737 } // end of namespace Streaming
738
Note: See TracBrowser for help on using the browser.