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

Revision 729, 22.0 kB (checked in by ppalmers, 15 years ago)

some more transmit tweaks

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     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
708           it != m_IsoHandlers.end();
709           ++it )
710     {
711         (*it)->setVerboseLevel(i);
712     }
713 }
714
715 void IsoHandlerManager::dumpInfo() {
716     int i=0;
717
718     debugOutputShort( DEBUG_LEVEL_NORMAL, "Dumping IsoHandlerManager Stream handler information...\n");
719     debugOutputShort( DEBUG_LEVEL_NORMAL, " State: %d\n",(int)m_State);
720
721     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
722           it != m_IsoHandlers.end();
723           ++it )
724     {
725         debugOutputShort( DEBUG_LEVEL_NORMAL, " IsoHandler %d (%p)\n",i++,*it);
726
727         (*it)->dumpInfo();
728     }
729
730 }
731
732 } // end of namespace Streaming
733
Note: See TracBrowser for help on using the browser.