Back to index

nordugrid-arc-nox  1.1.0~rc6
Classes | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes | Friends
Arc::RunPump Class Reference
Collaboration diagram for Arc::RunPump:
Collaboration graph
[legend]

List of all members.

Classes

class  Abandoned

Private Member Functions

 RunPump (void)
 ~RunPump (void)
 operator bool (void)
bool operator! (void)
void Pump (void)
void Add (Run *r)
void Remove (Run *r)
void child_handler (Glib::Pid pid, int result)

Static Private Member Functions

static RunPumpInstance (void)

Private Attributes

std::list< Abandonedabandoned_
Glib::Mutex abandoned_lock_
Glib::Mutex list_lock_
Glib::Mutex pump_lock_
Glib::RefPtr< Glib::MainContext > context_
Glib::Thread * thread_

Static Private Attributes

static Glib::Mutex instance_lock_
static RunPumpinstance_ = NULL
static unsigned int mark_ = ~RunPumpMagic

Friends

class Run

Detailed Description

Definition at line 35 of file Run_unix.cpp.


Constructor & Destructor Documentation

Arc::RunPump::RunPump ( void  ) [private]

Definition at line 118 of file Run_unix.cpp.

    : context_(NULL),
      thread_(NULL) {
    try {
      thread_ = Glib::Thread::create(sigc::mem_fun(*this, &RunPump::Pump), false);
    } catch (Glib::Exception& e) {} catch (std::exception& e) {}
    ;
    if (thread_ == NULL)
      return;
    // Wait for context_ to be intialized
    // TODO: what to do if context never initialized
    for (;;) {
      if (context_)
        break;
      thread_->yield(); // This is simpler than condition+mutex
    }
  }

Here is the call graph for this function:

Here is the caller graph for this function:

Arc::RunPump::~RunPump ( void  ) [private]

Member Function Documentation

void Arc::RunPump::Add ( Run r) [private]

Definition at line 177 of file Run_unix.cpp.

                          {
    if (!r)
      return;
    if (!(*r))
      return;
    if (!(*this))
      return;
    // Take full control over context
    list_lock_.lock();
    while (true) {
      context_->wakeup();
      if (pump_lock_.trylock())
        break;
      sleep(1);
    }
    try {
      // Add sources to context
      if (r->stdout_str_ && !(r->stdout_keep_))
        r->stdout_conn_ = context_->signal_io().connect(sigc::mem_fun(*r, &Run::stdout_handler), r->stdout_, Glib::IO_IN | Glib::IO_HUP);
      if (r->stderr_str_ && !(r->stderr_keep_))
        r->stderr_conn_ = context_->signal_io().connect(sigc::mem_fun(*r, &Run::stderr_handler), r->stderr_, Glib::IO_IN | Glib::IO_HUP);
      if (r->stdin_str_ && !(r->stdin_keep_))
        r->stdin_conn_ = context_->signal_io().connect(sigc::mem_fun(*r, &Run::stdin_handler), r->stdin_, Glib::IO_OUT | Glib::IO_HUP);
#ifdef HAVE_GLIBMM_CHILDWATCH
      r->child_conn_ = context_->signal_child_watch().connect(sigc::mem_fun(*r, &Run::child_handler), r->pid_->pid());
      //if(r->child_conn_.empty()) std::cerr<<"connect for signal_child_watch failed"<<std::endl;
#endif
    } catch (Glib::Exception& e) {} catch (std::exception& e) {}
    ;
    pump_lock_.unlock();
    list_lock_.unlock();
  }

Here is the call graph for this function:

Here is the caller graph for this function:

void Arc::RunPump::child_handler ( Glib::Pid  pid,
int  result 
) [private]

Definition at line 238 of file Run_unix.cpp.

                                                     {
    abandoned_lock_.lock();
    for(std::list<Abandoned>::iterator a = abandoned_.begin();
                        a != abandoned_.end();++a) {
      if(a->pid_ == pid) {
        a->pid_ = 0;
        break;
      }
    }
    abandoned_lock_.unlock();
  }

Here is the caller graph for this function:

RunPump & Arc::RunPump::Instance ( void  ) [static, private]

Definition at line 136 of file Run_unix.cpp.

                                 {
    instance_lock_.lock();
    if ((instance_ == NULL) || (mark_ != RunPumpMagic)) {
      instance_ = new RunPump();
      mark_ = RunPumpMagic;
    }
    instance_lock_.unlock();
    return *instance_;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

Arc::RunPump::operator bool ( void  ) [inline, private]

Definition at line 60 of file Run_unix.cpp.

                        {
      return (bool)context_;
    }
bool Arc::RunPump::operator! ( void  ) [inline, private]

Definition at line 63 of file Run_unix.cpp.

                         {
      return !(bool)context_;
    }
void Arc::RunPump::Pump ( void  ) [private]

Definition at line 146 of file Run_unix.cpp.

                         {
    // TODO: put try/catch everythere for glibmm errors
    try {
      context_ = Glib::MainContext::create();
      // In infinite loop monitor state of children processes
      // and pump information to/from std* channels if requested
      //context_->acquire();
      for (;;) {
        list_lock_.lock();
        //      sleep(1);
        list_lock_.unlock();
        pump_lock_.lock();
        bool dispatched = context_->iteration(true);
        for(std::list<Abandoned>::iterator a = abandoned_.begin();
                            a != abandoned_.end();) {
          if(a->pid_ == 0) {
            SAFE_DISCONNECT(a->child_conn_);
            a = abandoned_.erase(a);
          } else {
            ++a;
          }
        }
        pump_lock_.unlock();
        thread_->yield();
        if (!dispatched)
          sleep(1);
      }
    } catch (Glib::Exception& e) {} catch (std::exception& e) {}
    ;
  }

Here is the caller graph for this function:

void Arc::RunPump::Remove ( Run r) [private]

Definition at line 210 of file Run_unix.cpp.

                             {
    if (!r)
      return;
    if (!(*r))
      return;
    if (!(*this))
      return;
    // Take full control over context
    list_lock_.lock();
    while (true) {
      context_->wakeup();
      if (pump_lock_.trylock())
        break;
      sleep(1);
    }
    // Disconnect sources from context
    SAFE_DISCONNECT(r->stdout_conn_);
    SAFE_DISCONNECT(r->stderr_conn_);
    SAFE_DISCONNECT(r->stdin_conn_);
    SAFE_DISCONNECT(r->child_conn_);
    if(r->running_) {
      abandoned_.push_back(Abandoned(r->pid_->pid(),context_->signal_child_watch().connect(sigc::mem_fun(*this,&RunPump::child_handler), r->pid_->pid())));
      r->running_ = false;
    };
    pump_lock_.unlock();
    list_lock_.unlock();
  }

Here is the call graph for this function:

Here is the caller graph for this function:


Friends And Related Function Documentation

friend class Run [friend]

Definition at line 36 of file Run_unix.cpp.


Member Data Documentation

std::list<Abandoned> Arc::RunPump::abandoned_ [private]

Definition at line 50 of file Run_unix.cpp.

Glib::Mutex Arc::RunPump::abandoned_lock_ [private]

Definition at line 52 of file Run_unix.cpp.

Glib::RefPtr<Glib::MainContext> Arc::RunPump::context_ [private]

Definition at line 55 of file Run_unix.cpp.

RunPump * Arc::RunPump::instance_ = NULL [static, private]

Definition at line 39 of file Run_unix.cpp.

Glib::Mutex Arc::RunPump::instance_lock_ [static, private]

Definition at line 38 of file Run_unix.cpp.

Glib::Mutex Arc::RunPump::list_lock_ [private]

Definition at line 53 of file Run_unix.cpp.

unsigned int Arc::RunPump::mark_ = ~RunPumpMagic [static, private]

Definition at line 40 of file Run_unix.cpp.

Glib::Mutex Arc::RunPump::pump_lock_ [private]

Definition at line 54 of file Run_unix.cpp.

Glib::Thread* Arc::RunPump::thread_ [private]

Definition at line 56 of file Run_unix.cpp.


The documentation for this class was generated from the following file: