root/branches/ppalmers-streaming/src/libstreaming/util/IsoHandlerManager.cpp

Revision 723, 22.0 kB (checked in by ppalmers, 14 years ago)

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