[Ace-users] [ace-users] ACE_Process_Manager problem

Spang, Oliver (NSN - DE/Bruchsal) oliver.spang at nsn.com
Wed Nov 21 08:29:50 CST 2007


    ACE VERSION: 5.6.1

    HOST MACHINE and OPERATING SYSTEM:
Linux, Fedora Core 5

    TARGET MACHINE and OPERATING SYSTEM, if different from HOST:
    COMPILER NAME AND VERSION (AND PATCHLEVEL):

    THE $ACE_ROOT/ace/config.h FILE 
config_linux.h

    THE $ACE_ROOT/include/makeinclude/platform_macros.GNU FILE
platform_linux.GNU

    SYNOPSIS:
Problem spawning process with ACE_Process_Manager while waiting for end
of another process

    DESCRIPTION:
I spawn several processes using ACE_Process_Manager. The problem is,
while I wait() for a process, further spawn()'s won't return.

    REPEAT BY:
I tracked this down to the following ACE code:
in Process_Manager.cpp, spawn(), we have (line 446...):
  pid_t const pid = process->spawn (options);

  // Only include the pid in the parent's table.
  if (pid == ACE_INVALID_PID || pid == 0)
    return pid;

  ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
                            ace_mon, this->lock_, -1));

  if (this->append_proc (process, event_handler) == -1)
    // bad news: spawned, but not registered in table.
    return ACE_INVALID_PID;
------------------------------------------------------------------------
------------
in Process_Manager.cpp, wait(), we have (line 789...):
  ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
this->lock_, -1));

  if (pid != 0)
    {
      idx = this->find_proc (pid);
      if (idx == -1)
        return ACE_INVALID_PID;
      else
        proc = process_table_[idx].process_;
    }

  if (proc != 0)
    pid = proc->wait (timeout, status);
------------------------------------------------------------------------
-------------

This means, spawn() tries to acquire this->lock_, which is already hold
by wait().
Is this the way, ACE_Process_Manager should work?
Isn't it possible to release the lock_ after the access to the
process_table (find_proc()), and acquire it again after the wait()?


    SAMPLE FIX/WORKAROUND:
My workaround is to wait with this code, not very nice ;-)
    while ((iResult=ACE_Process_Manager::instance ()->wait (iProcessId,
TIME_100ms, &t_Status)==0))
    {
        ACE_Thread::yield ();
    }



More information about the Ace-users mailing list