[Sofaswitch-svn] [commit] r151 - sofaswitch/trunk/mcu
Author: derek Date: Fri Oct 27 22:30:31 2006 New Revision: 151 Modified: sofaswitch/trunk/mcu/conferenceroom.cxx sofaswitch/trunk/mcu/manager.cxx sofaswitch/trunk/mcu/manager.h sofaswitch/trunk/mcu/member.cxx sofaswitch/trunk/mcu/member.h sofaswitch/trunk/mcu/participant.cxx Log: More tidyups. Move to nicer variable names, and fix PSafePtr issues, and get threading closer to right. Modified: sofaswitch/trunk/mcu/conferenceroom.cxx ============================================================================== --- sofaswitch/trunk/mcu/conferenceroom.cxx (original) +++ sofaswitch/trunk/mcu/conferenceroom.cxx Fri Oct 27 22:30:31 2006 @@ -84,26 +84,32 @@ PStringList ConferenceRoom::GetParticipantNames() { PWaitAndSignal m(memberListLock); - PStringList participants = memberList; + PStringList participants; + for (PINDEX i = 0; i < memberList.GetSize(); i++) + participants += PString(memberList[i]); + PTRACE(3, "Participants in " << roomId << " is " << participants); - return memberList; + return participants; } PStringList ConferenceRoom::AddNewMember(PString memberId) { PTRACE(3, "Add member " << memberId << " to " << roomId); - PStringList currentMembers = memberList; PWaitAndSignal m(memberListLock); - currentMembers = memberList; + PStringList currentMembers; + for (PINDEX i = 0; i < memberList.GetSize(); i++) + currentMembers += PString(memberList[i]); + memberList.AppendString(memberId); - + return currentMembers; + } void ConferenceRoom::OnReleaseThreadMain(PThread &, INT) { - SafeDereference(); manager.RemoveConferenceRoomId(roomId); + SafeDereference(); } void ConferenceRoom::Clear() Modified: sofaswitch/trunk/mcu/manager.cxx ============================================================================== --- sofaswitch/trunk/mcu/manager.cxx (original) +++ sofaswitch/trunk/mcu/manager.cxx Fri Oct 27 22:30:31 2006 @@ -72,10 +72,10 @@ activeCalls.Initialise(); deadCommsInstances.Initialise(); - garbageCollector = PThread::Create(PCREATE_NOTIFIER(GarbageMain), 0, - PThread::NoAutoDeleteThread, - PThread::LowPriority, - "purge Manager Lists"); + PThread::Create(PCREATE_NOTIFIER(GarbageMain), 0, + PThread::AutoDeleteThread, + PThread::LowPriority, + "purge Manager Lists"); } @@ -90,7 +90,9 @@ delete & supervisor; - RemoveGarbageCollector(); + garbageExit.Signal(); + + garbageFinished.Wait(); } Comms * Manager::ClearCommsId(const PString &memberId) @@ -125,13 +127,6 @@ return NULL; } -void Manager::RemoveGarbageCollector() -{ - garbageExit.Signal(); - garbageCollector->WaitForTermination(); - delete garbageCollector; -} - void Manager::GarbageMain(PThread &, INT) { while (!garbageExit.Wait(1000)) { @@ -146,6 +141,7 @@ PTRACE(3, "Connections size is " << activeMembers.GetSize()); } PTRACE(3, "Garbage exit can happen, as they are all gone "); + garbageFinished.Signal(); } void Manager::CollectGarbage() @@ -180,12 +176,18 @@ PSafePtr <Member> member = activeMembers.FindWithLock(memberId, PSafeReadOnly); if (member != NULL) - member->RemoveFromRoom(); + member->Clear(); } +} - PTRACE(3, "Remove MemberID \"" << memberId << "\" PARTIAL"); - activeMembers.RemoveAt(memberId); - PTRACE(3, "Remove MemberID \"" << memberId << "\" DONE"); +void Manager::OnReleased(const PString & memberId) +{ + PTRACE(3, "Manager\tOnReleased " << memberId << " is now deleting"); + + if (activeMembers.FindWithLock(memberId, PSafeReadWrite) != NULL) { + PTRACE(3, "Manager\tOnReleased " << memberId << ".. Now do RemoveAt()"); + activeMembers.RemoveAt(memberId); + } } @@ -199,36 +201,38 @@ { PTRACE(3, "Manager\t request room " << cmd[1] << " and an id"); PString roomId = cmd[1]; - PSafePtr <ConferenceRoom> room; { PWaitAndSignal m(activeRooms.GetMutex()); /**Prevent adding two conferences of same name */ - room = activeRooms.FindWithLock(roomId, PSafeReadOnly); + PSafePtr <ConferenceRoom> room = activeRooms.FindWithLock(roomId, PSafeReadOnly); if (room == NULL) { /*The room does not exist */ PTRACE(3, "Prior Create Conference room, size is " << activeRooms.GetSize()); PTRACE(3, "Create the room " << roomId << " in the conference server"); - room = new ConferenceRoom(*this, roomId); - activeRooms.SetAt(roomId, room); + PSafePtr <ConferenceRoom > rm = new ConferenceRoom(*this, roomId); + activeRooms.SetAt(roomId, rm); PTRACE(3, "Finished Create Conference room, size is " << activeRooms.GetSize()); } else { PTRACE(3, "No need to create conference room " << roomId << " as it already exists"); } } + PSafePtr <ConferenceRoom> room = activeRooms.FindWithLock(roomId, PSafeReadOnly); + if (room == NULL) + return; + Comms *c = runningComms->GetNextComms(); if (c == NULL) return; c->SetRemoteController(requester); PTRACE(3, "Prior Create Member, size is " << activeMembers.GetSize()); - PSafePtr <Member> member = new Member(*this, room->GetRoomId(), c->GetOurId()); + PSafePtr <Member> member = new Member(*this, roomId, c->GetOurId()); activeMembers.SetAt(c->GetOurId(), member); PTRACE(3, "Have created member, " << c->GetOurId()); PStringList currentMembers = room->AddNewMember(c->GetOurId()); - FillMembershipList *f = new FillMembershipList(*this, currentMembers, c->GetOurId()); - f->Resume(); + new FillMembershipList(*this, currentMembers, c->GetOurId()); PTRACE(3, "Have created member, " << c->GetOurId() << " and filled membership list"); nodesMakingCalls.AddNewMessageFrame(c); Modified: sofaswitch/trunk/mcu/manager.h ============================================================================== --- sofaswitch/trunk/mcu/manager.h (original) +++ sofaswitch/trunk/mcu/manager.h Fri Oct 27 22:30:31 2006 @@ -156,14 +156,14 @@ void ThisFrameHasDied(MessageFrame *c) { deadCommsInstances.AddNewMessageFrame(c); } + /**Callback for removing a connection from the list of active + connections */ + void OnReleased(const PString & memberId); protected: /**Go through the list of active calls, and tell them to "die now" */ void RemoveAllCalls(); - - /**Remove and terminate the garbage collector thread */ - void RemoveGarbageCollector(); /**The interface to the external script which runs python, to provide comms for us */ LaunchNewId &lid; @@ -219,13 +219,13 @@ /**@name Clean up dead activeMembers */ //@{ - /**The thread which runs every second to look for TCPConnections to delete */ - PThread *garbageCollector; - /**The syncpoint that flags when we exit, and is used to time the 1 second gaps between cleaning */ PSyncPoint garbageExit; + /**The syncpoint that the garbage collection thread fires on finishing. */ + PSyncPoint garbageFinished; + /**The method which does the garbage collection */ void CollectGarbage(); Modified: sofaswitch/trunk/mcu/member.cxx ============================================================================== --- sofaswitch/trunk/mcu/member.cxx (original) +++ sofaswitch/trunk/mcu/member.cxx Fri Oct 27 22:30:31 2006 @@ -84,6 +84,8 @@ buffer = new BYTE[bufferSize]; memset(buffer, 0, bufferSize); currentWriteIndex = 0; + + isClearing = FALSE; } Member::~Member() @@ -134,21 +136,6 @@ } -void Member::RemoveFromRoom() -{ - PTRACE(3, "Remove this member " << memberId - << " from conference room " << roomId); - - keepGoing = FALSE; - - SafeReference(); //Guarantee this class won't be deleted "under our feet" - PString name = "%X mdel " + memberId; - PThread::Create(PCREATE_NOTIFIER(EmptyParticipantDict), 0, - PThread::AutoDeleteThread, - PThread::NormalPriority, - name); -} - void Member::DestroyThisParticipant(const PString &partyKey) { PTRACE(3, "Member " << memberId << " is now to remove participant " << partyKey); @@ -278,6 +265,60 @@ dst_ptr++; } } + +void Member::Clear() +{ + { + PWaitAndSignal m(clearMutex); + if (isClearing) + return; + isClearing = TRUE; + } + + PTRACE(3, *this << " is now doing a CLEAR for sure."); + // Add a reference for the thread we are about to start + SafeReference(); + PString clearName = PString("OnRelease ") + memberId; + PThread::Create(PCREATE_NOTIFIER(OnReleaseThreadMain), 30000, + PThread::AutoDeleteThread, + PThread::NormalPriority, + clearName); +} + + +void Member::OnReleaseThreadMain(PThread &, INT) +{ + PTRACE(3, "OnRelease thread started for " << *this); + + { + PSafePtr <ConferenceRoom> conferenceRoom = manager.GetConferenceRoom(roomId); + if (conferenceRoom != NULL) { + conferenceRoom->RemoveMember(memberId); + } else { + PTRACE(3, "ERROR Could not remove " << memberId << " from the conference room " ); + PTRACE(3, roomId << "as " << roomId << " has gone"); + } + } + + participants.EmptyParticipantDict(); + participants.WaitForTotallyEmpty(); + + + OnReleased(); + + PTRACE(3, "Member\tOnRelease thread completed for " << *this); + // Dereference on the way out of the thread + SafeDereference(); +} + + +void Member::OnReleased() +{ + PTRACE(3, "Member\tOnReleased " << *this); + + manager.OnReleased(memberId); +} + ///////////////////////////////////////////////////////////////////////////// MemberConsumer::MemberConsumer(Member *m) :PThread(10000, AutoDeleteThread, LowPriority, "%X member delete"), @@ -309,6 +350,7 @@ targetMemberId(_targetMemberId) { PTRACE(3, "Constructor:: " << *this); + Resume(); } FillMembershipList::~FillMembershipList() @@ -342,10 +384,10 @@ return; for(PINDEX i = 0; i < membersToAdd.GetSize(); i++) { - PSafePtr <Member> other = manager.GetMember(membersToAdd[i]); - if ((other != NULL) && (other->GetMemberId() != targetMember->GetMemberId())) { + PSafePtr <Member> otherMember = manager.GetMember(membersToAdd[i]); + if ((otherMember != NULL) && (otherMember->GetMemberId() != targetMember->GetMemberId())) { targetMember->AddMemberToRoom(membersToAdd[i]); - other->AddMemberToRoom(targetMemberId); + otherMember->AddMemberToRoom(targetMemberId); } } Modified: sofaswitch/trunk/mcu/member.h ============================================================================== --- sofaswitch/trunk/mcu/member.h (original) +++ sofaswitch/trunk/mcu/member.h Fri Oct 27 22:30:31 2006 @@ -91,9 +91,6 @@ members */ void AddMemberToRoom(const PString & newMember); - /**Remove this member from the conference room*/ - void RemoveFromRoom(); - /**A member of this conference room has ended.Consequently, the Participant for that member has died. Since we point to that member via a matching Participant, we have to remove that member @@ -140,6 +137,10 @@ conference */ PString GetConferenceParticipants(); + /**End this particular Member, This is the method to call, if you want this + Member to die good. */ + void Clear(); + protected: /**Do the multiplexing of audio together */ @@ -198,6 +199,30 @@ /**The time at which this structure was created, which is the time this call * was started at */ PTime memberCreatedAt; + +#ifdef DOC_PLUS_PLUS + /**This contains the 1 notifier that is used when closing down this + instance of TcpConnection class. It is called by a custom + thread, which deletes the class */ + virtual void OnReleaseThreadMain(PThread &, INT); +#else + PDECLARE_NOTIFIER(PThread, Member, OnReleaseThreadMain); +#endif + + /**Clean up the termination of the connection. + This function can do any internal cleaning up and waiting on background + threads that may be using the connection object. + + The default behaviour calls the ConferenceServer function of the same name. + */ + virtual void OnReleased(); + + /**Mutex to protect access to the isClearing flag, which ensures that only + one thread attempts to clear this connection */ + PMutex clearMutex; + + /**Flag to indicate we are being cleared, or have been cleared */ + BOOL isClearing; }; Modified: sofaswitch/trunk/mcu/participant.cxx ============================================================================== --- sofaswitch/trunk/mcu/participant.cxx (original) +++ sofaswitch/trunk/mcu/participant.cxx Fri Oct 27 22:30:31 2006 @@ -211,8 +211,14 @@ const PString & srcMember, const PString & dstMember) { - PSafePtr <Member> dstMemberPtr = mgr.GetMember(dstMember); - if (dstMemberPtr != NULL) { + { + PWaitAndSignal m(addNewParticipantMutex); + if (shuttingDown) + return; + } + + PSafePtr <Member> dstMemberPtr = mgr.GetMember(dstMember); + if (dstMemberPtr != NULL) { PSafePtr <Participant> participant = new Participant(mgr, *this, srcMember, dstMemberPtr); SetAt(participant->GetKey(), participant); @@ -222,13 +228,19 @@ void ParticipantDict::EmptyParticipantDict() { - PTRACE(3, "Start Empty participant list"); - PTRACE(3, "participant dict start with size of " << GetSize()); + { + PWaitAndSignal m(addNewParticipantMutex); + if (shuttingDown) + return; + shuttingDown = TRUE; + } - RemoveAll(); - - PTRACE(3, "Done Empty participant list"); - PTRACE(3, "participant dict now has size of " << GetSize()); + PTRACE(3, "Empty participantDict for Dictionary of \"" << *this << "\""); + for (PSafePtr<Participant> participant(*this, PSafeReadOnly); participant != + NULL; ++participant) { + PTRACE(3, "Empty participant member " << *participant); + participant->Clear(); + } }
participants (1)
-
SofaSWITCH SVN