[haiku-commits] r41315 - in haiku/branches/developer/bonefish/signals: headers/private/kernel src/system/kernel

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 4 May 2011 01:46:54 +0200 (CEST)

Author: bonefish
Date: 2011-05-04 01:46:53 +0200 (Wed, 04 May 2011)
New Revision: 41315
Changeset: https://dev.haiku-os.org/changeset/41315

Modified:
   
haiku/branches/developer/bonefish/signals/headers/private/kernel/thread_types.h
   haiku/branches/developer/bonefish/signals/src/system/kernel/team.cpp
Log:
* Derived ProcessSession and ProcessGroup from BReferenceable and got rid of
  their respective reference count (group_count, refs).
* Made ProcessGroup::session private, renamed it to fSession, and added a getter
  (Session()) and an extended setter (Publish()).
* Got rid of the now superfluous insert_group_into_session(),
  remove_group_from_session(), acquire_process_group_ref(),
  release_process_group_ref().
* _user_setsid(): Added TODO.


Modified: 
haiku/branches/developer/bonefish/signals/headers/private/kernel/thread_types.h
===================================================================
--- 
haiku/branches/developer/bonefish/signals/headers/private/kernel/thread_types.h 
    2011-05-03 22:59:49 UTC (rev 41314)
+++ 
haiku/branches/developer/bonefish/signals/headers/private/kernel/thread_types.h 
    2011-05-03 23:46:53 UTC (rev 41315)
@@ -412,9 +412,8 @@
 };
 
 
-struct ProcessSession {
+struct ProcessSession : BReferenceable {
        pid_t                           id;
-       int32                           group_count;
        int32                           controlling_tty;        // index of the 
controlling tty,
                                                                                
        // -1 if none
        pid_t                           foreground_group;
@@ -433,11 +432,9 @@
 };
 
 
-struct ProcessGroup : DeferredDeletable {
+struct ProcessGroup : DeferredDeletable, BReferenceable {
        struct ProcessGroup *next;              // next in hash
-       struct ProcessSession *session;
        pid_t                           id;
-       int32                           refs;
        BKernel::Team           *teams;
        bool                            orphaned;
 
@@ -450,8 +447,16 @@
                        void                            Unlock()
                                                                        { 
mutex_unlock(&fLock); }
 
+                       ProcessSession*         Session() const
+                                                                       { 
return fSession; }
+                       void                            Publish(ProcessSession* 
session);
+
+protected:
+       virtual void                            LastReferenceReleased();
+
 private:
                        mutex                           fLock;
+                       ProcessSession*         fSession;
 };
 
 }      // namespace BKernel

Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/team.cpp
===================================================================
--- haiku/branches/developer/bonefish/signals/src/system/kernel/team.cpp        
2011-05-03 22:59:49 UTC (rev 41314)
+++ haiku/branches/developer/bonefish/signals/src/system/kernel/team.cpp        
2011-05-03 23:46:53 UTC (rev 41315)
@@ -739,11 +739,10 @@
 
 ProcessGroup::ProcessGroup(pid_t id)
        :
-       session(NULL),
        id(id),
-       refs(0),
        teams(NULL),
-       orphaned(true)
+       orphaned(true),
+       fSession(NULL)
 {
        char lockName[32];
        snprintf(lockName, sizeof(lockName), "Group:%" B_PRId32, id);
@@ -755,25 +754,43 @@
 {
        TRACE(("ProcessGroup::~ProcessGroup(): id = %ld\n", group->id));
 
-       // remove_group_from_session() keeps this pointer around
-       // only if the session can be freed as well
-       if (session != NULL) {
-               TRACE(("ProcessGroup::~ProcessGroup(): frees session %ld\n",
-                       session->id));
-               delete session;
+       if (fSession != NULL) {
+               sGroupHash.RemoveUnchecked(this);
+               fSession->ReleaseReference();
        }
 
        mutex_destroy(&fLock);
 }
 
 
+/*!    Adds the group the given session and makes it publicly accessible.
+       The teams lock must be held.
+*/
+void
+ProcessGroup::Publish(ProcessSession* session)
+{
+       fSession = session;
+       sGroupHash.InsertUnchecked(this);
+       session->AcquireReference();
+}
+
+
+void
+ProcessGroup::LastReferenceReleased()
+{
+       if (are_interrupts_enabled())
+               delete this;
+       else
+               deferred_delete(this);
+}
+
+
 //     #pragma mark - ProcessSession
 
 
 ProcessSession::ProcessSession(pid_t id)
        :
        id(id),
-       group_count(0),
        controlling_tty(-1),
        foreground_group(-1)
 {
@@ -949,93 +966,17 @@
 }
 
 
-/*!    Removes a group from a session, and puts the session object
-       back into the session cache, if it's not used anymore.
-       You must hold the team lock when calling this function.
-*/
-static void
-remove_group_from_session(ProcessGroup* group)
-{
-       ProcessSession* session = group->session;
-
-       // the group must be in any session to let this function have any effect
-       if (session == NULL)
-               return;
-
-       sGroupHash.RemoveUnchecked(group);
-
-       // we cannot free the resource here, so we're keeping the group link
-       // around - this way it'll be freed by free_process_group()
-       if (--session->group_count > 0)
-               group->session = NULL;
-}
-
-
-/*!    Team lock must be held.
-*/
-static void
-acquire_process_group_ref(pid_t groupID)
-{
-       ProcessGroup* group = team_get_process_group_locked(NULL, groupID);
-       if (group == NULL) {
-               panic("acquire_process_group_ref(): unknown group ID: %ld", 
groupID);
-               return;
-       }
-
-       group->refs++;
-}
-
-
-/*!    Team lock must be held.
-*/
-static void
-release_process_group_ref(pid_t groupID)
-{
-       ProcessGroup* group = team_get_process_group_locked(NULL, groupID);
-       if (group == NULL) {
-               panic("release_process_group_ref(): unknown group ID: %ld", 
groupID);
-               return;
-       }
-
-       if (group->refs <= 0) {
-               panic("release_process_group_ref(%ld): ref count already 0", 
groupID);
-               return;
-       }
-
-       if (--group->refs > 0)
-               return;
-
-       // group is no longer used
-
-       remove_group_from_session(group);
-       deferred_delete(group);
-}
-
-
 /*!    You must hold the team lock when calling this function. */
 static void
-insert_group_into_session(ProcessSession* session, ProcessGroup* group)
-{
-       if (group == NULL)
-               return;
-
-       group->session = session;
-       sGroupHash.InsertUnchecked(group);
-       session->group_count++;
-}
-
-
-/*!    You must hold the team lock when calling this function. */
-static void
 insert_team_into_group(ProcessGroup* group, Team* team)
 {
        team->group = group;
        team->group_id = group->id;
-       team->session_id = group->session->id;
+       team->session_id = group->Session()->id;
 
        team->group_next = group->teams;
        group->teams = team;
-       acquire_process_group_ref(group->id);
+       group->AcquireReference();
 }
 
 
@@ -1071,7 +1012,7 @@
        team->group = NULL;
        team->group_next = NULL;
 
-       release_process_group_ref(group->id);
+       group->ReleaseReference();
 }
 
 
@@ -1920,7 +1861,7 @@
        Team* team;
 
        ProcessGroup* group = team_get_process_group_locked(
-               parent->group->session, groupID);
+               parent->group->Session(), groupID);
        if (group == NULL)
                return false;
 
@@ -1982,7 +1923,17 @@
 {
        if (has_group_ref) {
                InterruptsSpinLocker locker(gTeamSpinlock);
-               release_process_group_ref(group_id);
+
+               ProcessGroup* group = team_get_process_group_locked(NULL, 
group_id);
+               if (group == NULL) {
+                       panic("job_control_entry::~job_control_entry(): unknown 
group "
+                               "ID: %ld", group_id);
+                       return;
+               }
+
+               locker.Unlock();
+
+               group->ReleaseReference();
        }
 }
 
@@ -1993,15 +1944,16 @@
 job_control_entry::InitDeadState()
 {
        if (team != NULL) {
-               Thread* thread = team->main_thread;
                group_id = team->group_id;
+               team->group->AcquireReference();
+               has_group_ref = true;
+
+               Thread* thread = team->main_thread;
                this->thread = thread->id;
                status = thread->exit.status;
                reason = thread->exit.reason;
                signal = thread->exit.signal;
                team = NULL;
-               acquire_process_group_ref(group_id);
-               has_group_ref = true;
        }
 }
 
@@ -2235,7 +2187,7 @@
                if (team->id != dyingProcess && parent != NULL
                        && parent->id != dyingProcess
                        && parent->group_id != group->id
-                       && parent->session_id == group->session->id) {
+                       && parent->session_id == group->Session()->id) {
                        return false;
                }
 
@@ -2290,12 +2242,14 @@
        session = new(std::nothrow) ProcessSession(1);
        if (session == NULL)
                panic("Could not create initial session.\n");
+       BReference<ProcessSession> sessionReference(session, true);
 
        group = new(std::nothrow) ProcessGroup(1);
        if (group == NULL)
                panic("Could not create initial process group.\n");
+       BReference<ProcessGroup> groupReference(group, true);
 
-       insert_group_into_session(session, group);
+       group->Publish(session);
 
        // create the kernel team
        sKernelTeam = Team::Create("kernel_team", true);
@@ -2433,7 +2387,7 @@
 team_get_process_group_locked(ProcessSession* session, pid_t id)
 {
        ProcessGroup* group = sGroupHash.Lookup(id);
-       if (group != NULL && (session == NULL || session == group->session))
+       if (group != NULL && (session == NULL || session == group->Session()))
                return group;
 
        return NULL;
@@ -2447,8 +2401,8 @@
 
        InterruptsSpinLocker _(gTeamSpinlock);
 
-       team->group->session->controlling_tty = ttyIndex;
-       team->group->session->foreground_group = -1;
+       team->group->Session()->controlling_tty = ttyIndex;
+       team->group->Session()->foreground_group = -1;
 }
 
 
@@ -2459,7 +2413,7 @@
 
        InterruptsSpinLocker _(gTeamSpinlock);
 
-       return team->group->session->controlling_tty;
+       return team->group->Session()->controlling_tty;
 }
 
 
@@ -2471,7 +2425,7 @@
 
        InterruptsSpinLocker locker(gTeamSpinlock);
 
-       ProcessSession* session = team->group->session;
+       ProcessSession* session = team->group->Session();
 
        // must be the controlling tty of the calling process
        if (session->controlling_tty != ttyIndex)
@@ -2495,7 +2449,7 @@
                return B_INTERRUPTED;
        }
 
-       team->group->session->foreground_group = processGroupID;
+       team->group->Session()->foreground_group = processGroupID;
 
        return B_OK;
 }
@@ -2531,8 +2485,8 @@
        // If we're a controlling process (i.e. a session leader with 
controlling
        // terminal), there's a bit of signalling we have to do.
        if (team->session_id == team->id
-               && team->group->session->controlling_tty >= 0) {
-               ProcessSession* session = team->group->session;
+               && team->group->Session()->controlling_tty >= 0) {
+               ProcessSession* session = team->group->Session();
 
                session->controlling_tty = -1;
 
@@ -3607,9 +3561,9 @@
                // below.
                group->orphaned = true;
        }
+       BReference<ProcessGroup> groupReference(group, true);
 
        status_t status = B_OK;
-       ProcessGroup* freeGroup = NULL;
 
        InterruptsSpinLocker locker(gTeamSpinlock);
 
@@ -3624,19 +3578,17 @@
                        status = EACCES;
                } else if (team->group_id == groupID) {
                        // the team is already in the desired process group
-                       freeGroup = group;
                } else {
                        // Check if a process group with the requested ID 
already exists.
-                       ProcessGroup* targetGroup
-                               = 
team_get_process_group_locked(team->group->session, groupID);
+                       ProcessGroup* targetGroup = 
team_get_process_group_locked(
+                               team->group->Session(), groupID);
                        if (targetGroup != NULL) {
                                // In case of processID == groupID we have to 
free the
                                // allocated group.
-                               freeGroup = group;
                        } else if (processID == groupID) {
                                // We created a new process group, let us 
insert it into the
                                // team's session.
-                               insert_group_into_session(team->group->session, 
group);
+                               group->Publish(team->group->Session());
                                targetGroup = group;
                        }
 
@@ -3683,13 +3635,6 @@
 
        locker.Unlock();
 
-       if (status != B_OK) {
-               // in case of error, the group hasn't been added into the hash
-               delete group;
-       }
-
-       delete freeGroup;
-
        return status == B_OK ? groupID : status;
 }
 
@@ -3710,12 +3655,12 @@
        group = new(std::nothrow) ProcessGroup(team->id);
        if (group == NULL)
                return B_NO_MEMORY;
+       BReference<ProcessGroup> groupReference(group, true);
 
        session = new(std::nothrow) ProcessSession(group->id);
-       if (session == NULL) {
-               delete group;
+       if (session == NULL)
                return B_NO_MEMORY;
-       }
+       BReference<ProcessSession> sessionReference(session, true);
 
        state = disable_interrupts();
        GRAB_TEAM_LOCK();
@@ -3724,19 +3669,22 @@
        if (!is_process_group_leader(team)) {
                remove_team_from_group(team);
 
-               insert_group_into_session(session, group);
+               group->Publish(session);
                insert_team_into_group(group, team);
+
+               // TODO: We need to update the orphaned state of children's 
process
+               // groups. If a child was in our process group or in another 
session
+               // nothing will change for its process group, but if it was in 
another
+               // process group of the same session, that process group might 
now be
+               // orphaned.
        } else
                failed = true;
 
        RELEASE_TEAM_LOCK();
        restore_interrupts(state);
 
-       if (failed) {
-               delete group;
-               delete session;
+       if (failed)
                return B_NOT_ALLOWED;
-       }
 
        return team->group_id;
 }


Other related posts:

  • » [haiku-commits] r41315 - in haiku/branches/developer/bonefish/signals: headers/private/kernel src/system/kernel - ingo_weinhold