Author: bonefish Date: 2009-12-10 17:00:42 +0100 (Thu, 10 Dec 2009) New Revision: 34618 Changeset: http://dev.haiku-os.org/changeset/34618/haiku Modified: haiku/trunk/src/apps/cortex/NodeManager/NodeManager.cpp Log: * Don't lock the audio mixer connection. At least to me it seems handy to play with it as well. * Automatic whitespace cleanup. Modified: haiku/trunk/src/apps/cortex/NodeManager/NodeManager.cpp =================================================================== --- haiku/trunk/src/apps/cortex/NodeManager/NodeManager.cpp 2009-12-10 15:46:37 UTC (rev 34617) +++ haiku/trunk/src/apps/cortex/NodeManager/NodeManager.cpp 2009-12-10 16:00:42 UTC (rev 34618) @@ -38,10 +38,10 @@ const char* const _connectionField = "__connection_id"; const char* const _sourceNodeField = "__source_node_id"; const char* const _destNodeField = "__destination_node_id"; - + // -------------------------------------------------------- // // *** hooks // -------------------------------------------------------- // @@ -57,7 +57,7 @@ void NodeManager::nodeDeleted( const NodeRef* ref) {} - + void NodeManager::connectionMade( Connection* connection) {} @@ -95,7 +95,7 @@ bool recurse, Op operation, _for_each_state* state) { - + // PRINT(("### _do_for_each_connected()\n")); ASSERT(manager->IsLocked()); @@ -109,7 +109,7 @@ // already visited return; } - + // used to walk connections vector<Connection> connections; @@ -119,32 +119,32 @@ // walk input connections origin->getInputConnections(connections); for(uint32 n = 0; n < connections.size(); ++n) { - + if(!connections[n].isValid()) continue; - + // PRINT(("# source: %ld\n", connections[n].sourceNode())); - + NodeRef* targetRef; err = manager->getNodeRef( connections[n].sourceNode(), &targetRef); ASSERT(err == B_OK); ASSERT(targetRef); - + if(inGroup && targetRef->group() != inGroup) { // PRINT(("# .group mismatch\n")); // don't need to visit return; } - + // invoke operation // if(lockRef) // targetRef->lock(); operation(targetRef); // if(lockRef) // targetRef->unlock(); - + // recurse? if(recurse) _do_for_each_connected( @@ -155,7 +155,7 @@ operation, state); } - + // walk output connections connections.clear(); origin->getOutputConnections(connections); @@ -164,14 +164,14 @@ if(!connections[n].isValid()) continue; - + NodeRef* targetRef; err = manager->getNodeRef( connections[n].destinationNode(), &targetRef); ASSERT(err == B_OK); ASSERT(targetRef); - + if(inGroup && targetRef->group() != inGroup) { // PRINT(("# .group mismatch\n")); // don't need to visit @@ -184,7 +184,7 @@ operation(targetRef); // if(lockRef) // targetRef->unlock(); - + // recurse? if(recurse) _do_for_each_connected( @@ -206,12 +206,12 @@ // stop group before clearing [10aug99] group->_stop(); - + int32 n; while((n = group->countNodes()) > 0) { group->removeNode(n-1); } - + // // [e.moon 7nov99] release the group // status_t err = remove_observer(this, group); // if(err < B_OK) { @@ -221,7 +221,7 @@ // " %s\n", // group->id(), // strerror(err))); -// } +// } } inline void NodeManager::_freeConnection( @@ -237,7 +237,7 @@ connection->isValid() && connection->flags() & Connection::INTERNAL && !(connection->flags() & Connection::LOCKED)) { - + D_METHOD(( "! breaking connection:\n" " source node: %ld\n" @@ -267,7 +267,7 @@ strerror(err))); } } - + // delete delete connection; } @@ -289,9 +289,9 @@ it != m_nodeRefMap.end(); ++it) { deadNodes.push_back((*it).second); } - + // ungroup all nodes - + // [e.moon 13oct99] making PPC compiler happy // for_each( // m_nodeGroupSet.begin(), @@ -305,14 +305,14 @@ it != m_nodeGroupSet.end(); ++it) { _clearGroup(*it); } - + // delete groups ptr_set_delete( m_nodeGroupSet.begin(), m_nodeGroupSet.end()); m_nodeGroupSet.clear(); - + // deallocate all connections; disconnect internal nodes // [e.moon 13oct99] making PPC compiler happy // for_each( @@ -332,15 +332,15 @@ } m_conSourceMap.clear(); m_conDestinationMap.clear(); - + // release all nodes for(list<NodeRef*>::const_iterator it = deadNodes.begin(); it != deadNodes.end(); ++it) { (*it)->release(); } - + if(m_nodeRefMap.size()) { - // +++++ nodes will only remain if they have observers; cope! + // +++++ nodes will only remain if they have observers; cope! PRINT(("*** %ld nodes remaining!\n", m_nodeRefMap.size())); deadNodes.clear(); @@ -350,9 +350,9 @@ ptr_set_delete( deadNodes.begin(), - deadNodes.end()); + deadNodes.end()); } - + // for_each( // m_nodeRefMap.begin(), // m_nodeRefMap.end(), @@ -363,13 +363,13 @@ // ) // ) // ); -// +// // // delete all nodes // ptr_map_delete( // m_nodeRefMap.begin(), // m_nodeRefMap.end()); -// // +// // PRINT(( // "~NodeManager() done\n")); // @@ -400,13 +400,13 @@ "NodeManager()\n")); ASSERT(roster); - + // create refs for common nodes _initCommonNodes(); - // start the looper + // start the looper Run(); - + // initialize connection to the media roster D_ROSTER(("# roster->StartWatching(%p)\n", this)); roster->StartWatching(BMessenger(this)); @@ -435,26 +435,26 @@ *outRef = 0; return B_BAD_VALUE; } - + *outRef = (*it).second; return B_OK; } -// [13aug99] +// [13aug99] // fetches Connection corresponding to a given source/destination // on a given node. Returns an invalid connection and B_BAD_VALUE // if no matching connection was found. - + status_t NodeManager::findConnection( media_node_id node, const media_source& source, Connection* outConnection) const { Autolock _l(this); - + D_METHOD(( "NodeManager::findConnection()\n")); ASSERT(source != media_source::null); - + con_map::const_iterator it = m_conSourceMap.lower_bound(node); con_map::const_iterator itEnd = m_conSourceMap.upper_bound(node); for(; it != itEnd; ++it) @@ -463,21 +463,21 @@ *outConnection = *((*it).second); return B_OK; } - + *outConnection = Connection(); return B_BAD_VALUE; } - + status_t NodeManager::findConnection( media_node_id node, const media_destination& destination, Connection* outConnection) const { Autolock _l(this); - + D_METHOD(( "NodeManager::findConnection()\n")); ASSERT(destination != media_destination::null); - + con_map::const_iterator it = m_conDestinationMap.lower_bound(node); con_map::const_iterator itEnd = m_conDestinationMap.upper_bound(node); for(; it != itEnd; ++it) @@ -486,7 +486,7 @@ *outConnection = *((*it).second); return B_OK; } - + *outConnection = Connection(); return B_BAD_VALUE; } @@ -495,7 +495,7 @@ // fetches a Connection matching the given source and destination // nodes. Returns an invalid connection and B_BAD_VALUE if // no matching connection was found - + status_t NodeManager::findConnection( media_node_id sourceNode, media_node_id destinationNode, @@ -504,7 +504,7 @@ D_METHOD(( "NodeManager::findConnection(source %ld, dest %ld)\n", sourceNode, destinationNode)); - + con_map::const_iterator it = m_conSourceMap.lower_bound(sourceNode); con_map::const_iterator itEnd = m_conSourceMap.upper_bound(sourceNode); for(; it != itEnd; ++it) { @@ -513,7 +513,7 @@ return B_OK; } } - + *outConnection = Connection(); return B_BAD_VALUE; } @@ -531,11 +531,11 @@ media_node_id nodeA, media_node_id nodeB) { Autolock _l(this); - + D_METHOD(( "NodeManager::findRoute(%ld, %ld)\n", nodeA, nodeB)); status_t err; - + NodeRef* ref; err = getNodeRef(nodeA, &ref); if(err < B_OK) { @@ -544,9 +544,9 @@ nodeA, nodeB, nodeA)); return false; } - + _find_route_state st; - return _find_route_recurse(ref, nodeB, &st); + return _find_route_recurse(ref, nodeB, &st); } // implementation of above @@ -555,17 +555,17 @@ NodeRef* origin, media_node_id target, _find_route_state* state) { - + ASSERT(IsLocked()); ASSERT(origin); ASSERT(state); status_t err; - + // node already visited? if(state->visited.find(origin->id()) != state->visited.end()) { return false; } - + // mark node visited state->visited.insert(origin->id()); @@ -577,7 +577,7 @@ if(!connections[n].isValid()) continue; - + // test against target if(connections[n].sourceNode() == target) return true; // SUCCESS @@ -589,14 +589,14 @@ &ref); ASSERT(err == B_OK); ASSERT(ref); - + if(_find_route_recurse( ref, target, state)) return true; // SUCCESS } - + // walk output connections connections.clear(); origin->getOutputConnections(connections); @@ -604,7 +604,7 @@ if(!connections[n].isValid()) continue; - + // test against target if(connections[n].destinationNode() == target) return true; // SUCCESS @@ -616,7 +616,7 @@ &ref); ASSERT(err == B_OK); ASSERT(ref); - + if(_find_route_recurse( ref, target, @@ -644,7 +644,7 @@ const media_source& source, Connection* outConnection) const { Autolock _l(this); - + D_METHOD(( "NodeManager::findConnection()\n")); ASSERT(source != media_source::null); @@ -666,7 +666,7 @@ const media_destination& destination, Connection* outConnection) const { Autolock _l(this); - + D_METHOD(( "NodeManager::findConnection()\n")); ASSERT(destination != media_destination::null); @@ -687,7 +687,7 @@ // fetch NodeRefs for system nodes (if a particular node doesn't // exist, these methods return 0) - + NodeRef* NodeManager::audioInputNode() const { Autolock _l(this); return m_audioInputNode; @@ -713,7 +713,7 @@ // - you can write-lock the manager during sets of calls to these methods; // this ensures that the group set won't change. The methods do lock // the group internally, so locking isn't explicitly required. - + uint32 NodeManager::countGroups() const { Autolock _l(this); D_METHOD(( @@ -735,7 +735,7 @@ // look up a group by unique ID; returns B_BAD_VALUE if no // matching group was found - + class match_group_by_id : public binary_function<const NodeGroup*, uint32, bool> { public: @@ -757,12 +757,12 @@ m_nodeGroupSet.end(), bind2nd(match_group_by_id(), id) ); - + if(it == m_nodeGroupSet.end()) { *outGroup = 0; return B_BAD_VALUE; } - + *outGroup = *it; return B_OK; } @@ -791,35 +791,35 @@ m_nodeGroupSet.end(), bind2nd(match_group_by_name(), name) ); - + if(it == m_nodeGroupSet.end()) { *outGroup = 0; return B_BAD_VALUE; } - + *outGroup = *it; return B_OK; } // merge the given source group to the given destination; // empties and releases the source group - + status_t NodeManager::mergeGroups( NodeGroup* sourceGroup, NodeGroup* destinationGroup) { Autolock _l(this); - D_METHOD(( - "NodeManager::mergeGroups(name)\n")); + D_METHOD(( + "NodeManager::mergeGroups(name)\n")); status_t err; - - // [5feb00 c.lenz] already merged - if(sourceGroup->id() == destinationGroup->id()) - return B_OK; + // [5feb00 c.lenz] already merged + if(sourceGroup->id() == destinationGroup->id()) + return B_OK; + if(sourceGroup->isReleased() || destinationGroup->isReleased()) return B_NOT_ALLOWED; - + for(uint32 n = sourceGroup->countNodes(); n; --n) { NodeRef* node = sourceGroup->nodeAt(n-1); ASSERT(node); @@ -828,11 +828,11 @@ err = destinationGroup->addNode(node); ASSERT(err == B_OK); } - + // [7nov99 e.moon] delete the source group _removeGroup(sourceGroup); sourceGroup->release(); - + return B_OK; } @@ -855,12 +855,12 @@ public unary_function<NodeRef*, void> { public: NodeGroup* newGroup; - + _changeNodeGroupFn( NodeGroup* _newGroup) : newGroup(_newGroup) { ASSERT(newGroup); } - + void operator()( NodeRef* node) { @@ -873,7 +873,7 @@ err = oldGroup->removeNode(node); ASSERT(err == B_OK); } - + err = newGroup->addNode(node); ASSERT(err == B_OK); } @@ -886,7 +886,7 @@ ASSERT(insideNode); ASSERT(outsideNode); - + Autolock _l(this); // ensure that no route exists from insideNode to outsideNode @@ -896,7 +896,7 @@ insideNode->id(), outsideNode->id())); return B_NOT_ALLOWED; } - + // make sure the nodes share a common group NodeGroup* oldGroup = insideNode->group(); if(!oldGroup) { @@ -922,11 +922,11 @@ nameBuffer.String(), oldGroup->runMode()); *outGroup = newGroup; - + // move nodes connected to outsideNode from old to new group _changeNodeGroupFn fn(newGroup); fn(outsideNode); - + _for_each_state st; _do_for_each_connected( this, @@ -935,7 +935,7 @@ true, fn, &st); - + // [e.moon 1dec99] a single-node group takes that node's name if(newGroup->countNodes() == 1) newGroup->setName(newGroup->nodeAt(0)->name()); @@ -953,26 +953,26 @@ // can be properly serialized & reconstituted. // basic BMediaRoster::InstantiateDormantNode() wrapper - + status_t NodeManager::instantiate( const dormant_node_info& info, NodeRef** outRef, bigtime_t timeout, uint32 nodeFlags) { - + Autolock _l(this); status_t err; D_METHOD(( "NodeManager::instantiate()\n")); - + // * instantiate - + media_node node; - + if(m_useAddOnHost) { err = AddOnHost::InstantiateDormantNode( info, &node, timeout); - + if(err < B_OK) { node = media_node::null; @@ -989,15 +989,15 @@ err = AddOnHost::InstantiateDormantNode( info, &node, timeout); } - } + } } - + if(!m_useAddOnHost || node == media_node::null) { D_ROSTER(( "# roster->InstantiateDormantNode()\n")); err = roster->InstantiateDormantNode(info, &node); } - + if(err < B_OK) { *outRef = 0; return err; @@ -1015,7 +1015,7 @@ *outRef = 0; return B_BAD_INDEX; } - + // * create NodeRef NodeRef* ref = new NodeRef( node, @@ -1025,12 +1025,12 @@ ref->_setAddonHint(&info); _addRef(ref); - + // * return it *outRef = ref; return B_OK; } - + // SniffRef/Instantiate.../SetRefFor: a one-call interface // to create a node capable of playing a given media file. @@ -1046,12 +1046,12 @@ "NodeManager::instantiate(ref)\n")); // [no lock needed; calls the full form of instantiate()] - + status_t err; - + // * Find matching add-on dormant_node_info info; - + D_ROSTER(( "# roster->SniffRef()\n")); err = roster->SniffRef( @@ -1062,15 +1062,15 @@ *outRef = 0; return err; } - + // * Instantiate - err = instantiate(info, outRef, timeout, nodeFlags); - + err = instantiate(info, outRef, timeout, nodeFlags); + if(err < B_OK) return err; - + ASSERT(*outRef); - + // * Set file to play bigtime_t dur; D_ROSTER(("# roster->SetRefFor()\n")); @@ -1090,7 +1090,7 @@ // * update info [e.moon 29sep99] Autolock _l(*outRef); (*outRef)->_setAddonHint(&info, &file); - + return err; } @@ -1105,11 +1105,11 @@ Autolock _l(this); D_METHOD(( "NodeManager::reference()\n")); - + // should this node be marked _NO_RELEASE? NodeRef* ref = new NodeRef(node->Node(), this, nodeFlags, 0); _addRef(ref); - + *outRef = ref; return B_OK; } @@ -1122,12 +1122,12 @@ const media_input& input, const media_format& templateFormat, Connection* outConnection /*=0*/) { - + Autolock _l(this); status_t err; D_METHOD(( "NodeManager::connect()\n")); - + // * Find (& create if necessary) NodeRefs NodeRef* outputRef; @@ -1137,13 +1137,13 @@ NodeRef* inputRef; if(getNodeRef(input.node.node, &inputRef) < B_OK) inputRef = _addRefFor(input.node, 0); - + // * Connect the nodes - + media_output finalOutput; media_input finalInput; media_format finalFormat = templateFormat; - + D_ROSTER(("# roster->Connect()\n")); err = roster->Connect( output.source, @@ -1151,14 +1151,14 @@ &finalFormat, &finalOutput, &finalInput); - + if(err < B_OK) { if(outConnection) *outConnection = Connection(); connectionFailed(output, input, templateFormat, err); return err; } - + // * Create Connection instance; mark it INTERNAL // to automatically remove it upon shutdown. @@ -1193,16 +1193,16 @@ con->setOutputHint( output.name, output.format); - + con->setInputHint( input.name, input.format); con->setRequestedFormat( templateFormat); - + _addConnection(con); - + // [e.moon 10aug99] // fetch updated latencies; // [e.moon 28sep99] @@ -1210,15 +1210,15 @@ // newly-connected nodes and update their latencies -- this includes // recalculating the node's 'producer delay' if in B_RECORDING mode. - _updateLatenciesFrom(inputRef, true); - + _updateLatenciesFrom(inputRef, true); + // copy connection if(outConnection) { *outConnection = *con; } - return B_OK; + return B_OK; } - + // format-guessing form of connect(): tries to find // a common format between output & input before connection; // returns B_MEDIA_BAD_FORMAT if no common format appears @@ -1227,7 +1227,7 @@ // NOTE: the specifics of the input and output formats are ignored; // this method only looks at the format type, and properly // handles wildcards at that level (B_MEDIA_NO_TYPE). - + status_t NodeManager::connect( const media_output& output, const media_input& input, @@ -1240,7 +1240,7 @@ // defer to the pickier endpoint media_format f; - + if(output.format.type > B_MEDIA_UNKNOWN_TYPE) { f = output.format; if ((input.format.type > B_MEDIA_UNKNOWN_TYPE) && @@ -1259,7 +1259,7 @@ } // +++++ ? revert to wildcard ? - + // let the nodes try to work out a common format from here return connect( output, @@ -1273,7 +1273,7 @@ status_t NodeManager::disconnect( const Connection& connection) { - + Autolock _l(this); status_t err; D_METHOD(( @@ -1282,7 +1282,7 @@ // don't bother trying to disconnect an invalid connection if(!connection.isValid()) return B_NOT_ALLOWED; - + // make sure connection can be released if(connection.flags() & Connection::LOCKED) { PRINT(( @@ -1358,10 +1358,10 @@ Autolock _l(this); D_METHOD(( "NodeManager::createGroup()\n")); - + NodeGroup* g = new NodeGroup(name, this, runMode); _addGroup(g); - + return g; } @@ -1369,23 +1369,23 @@ // *** node/connection iteration // *** MUST BE LOCKED for any of these calls // -------------------------------------------------------- // - + // usage: // For the first call, pass 'cookie' a pointer to a void* set to 0. // Returns B_BAD_INDEX when the set of nodes has been exhausted (and // re-zeroes the cookie, cleaning up any unused memory.) - + status_t NodeManager::getNextRef( NodeRef** ref, void** cookie) { ASSERT(IsLocked()); ASSERT(cookie); - + if(!*cookie) *cookie = new node_ref_map::iterator(m_nodeRefMap.begin()); node_ref_map::iterator* pit = (node_ref_map::iterator*)*cookie; - + // at end of set? if(*pit == m_nodeRefMap.end()) { delete pit; @@ -1402,28 +1402,28 @@ // +++++ reworked 13sep99: dtors wouldn't have been called with 'delete *cookie'! +++++ void NodeManager::disposeRefCookie( void** cookie) { - + if(!cookie) return; - + node_ref_map::iterator* it = reinterpret_cast<node_ref_map::iterator*>(*cookie); ASSERT(it); if(it) delete it; -} - +} + status_t NodeManager::getNextConnection( Connection* connection, void** cookie) { ASSERT(IsLocked()); ASSERT(cookie); - + if(!*cookie) *cookie = new con_map::iterator(m_conSourceMap.begin()); con_map::iterator* pit = (con_map::iterator*)*cookie; - + // at end of set? if(*pit == m_conSourceMap.end()) { delete pit; @@ -1440,18 +1440,18 @@ // +++++ reworked 13sep99: dtors wouldn't have been called with 'delete *cookie'! +++++ void NodeManager::disposeConnectionCookie( void** cookie) { - + if(!cookie) return; - + con_map::iterator* it = reinterpret_cast<con_map::iterator*>(*cookie); ASSERT(it); if(it) delete it; -} - +} + // -------------------------------------------------------- // // *** BHandler impl // -------------------------------------------------------- // @@ -1471,7 +1471,7 @@ switch(message->what) { // *** Media Roster messages *** - + case B_MEDIA_NODE_CREATED: if(_handleNodesCreated(message) == B_OK) notify(message); [... truncated: 733 lines follow ...]