ROOT logo
// $Id: PipeEventor.cxx 2764 2012-06-09 03:17:46Z matevz $

// Copyright (C) 1999-2008, Matevz Tadel. All rights reserved.
// This file is part of GLED, released under GNU General Public License version 2.
// For the licensing terms see $GLEDSYS/LICENSE or http://www.gnu.org/.

//__________________________________________________________________________
// PipeEventor
//
// Spawns mCommand via gSystem->PipeOpen() in write mode.
// You can send data to be written to the pipe with SendCommand().
//

#include "PipeEventor.h"
#include <Gled/GThread.h>

#include <TSystem.h>

#include <signal.h>

ClassImp(PipeEventor);

/**************************************************************************/

void PipeEventor::_init()
{
  mPipe = 0;
  mWaitTimeMS = 1000;

  bSignalSafe = true;
}

/**************************************************************************/

void PipeEventor::OnStart(Operator::Arg* op_arg)
{
  Eventor::OnStart(op_arg);

  sigset_t set;

  sigemptyset(&set);
  sigaddset(&set, GThread::SigPIPE);
  pthread_sigmask(SIG_BLOCK, &set, 0);

  mPipe = gSystem->OpenPipe(mCommand.Data(), "w");
  if(!mPipe) {
    ISerr(GForm("PipeEventor::OnStart [%s] OpenPipe(%s) failed",
		GetName(), mCommand.Data()));
    return;
  }
  setlinebuf(mPipe);
}

void PipeEventor::OnExit(Operator::Arg* op_arg)
{
  if (mPipe)
  {
    gSystem->ClosePipe(mPipe);
    mPipe = 0;
  }
  ClearPendingCommands();

  Eventor::OnExit(op_arg);
}

/**************************************************************************/

void PipeEventor::Operate(Operator::Arg* op_arg)
{
  if (!mPipe)
  {
    throw Operator::Exception(this, Operator::OE_Break, "pipe closed");
  }

  mSendCond.Lock();
  try {
    feed_commands();
    mSendCond.TimedWait(GTime::MiliSec(mWaitTimeMS));
    feed_commands();
  }
  catch(Operator::Exception exc) {
    mSendCond.Unlock();
    throw;
  }
  mSendCond.Unlock();
}

/**************************************************************************/

void PipeEventor::PostCommand(TString& command)
{
  mSendCond.Lock();
  mPending.push_back(command);
  mSendCond.Signal();
  mSendCond.Unlock();
}

void PipeEventor::ClearPendingCommands()
{
  mSendCond.Lock();
  mPending.clear();
  mSendCond.Unlock();
}
/**************************************************************************/
// Protected methods
/**************************************************************************/

void PipeEventor::feed_commands()
{
  // Feeds commands (if any) from mPending to mPipe.
  // Caller must lock the mSendCond.

  if(ferror(mPipe)) {
    throw( Operator::Exception(this, Operator::OE_Break, "pipe closed") );
  }

  while(!mPending.empty()) {
    int ret = fprintf(mPipe, "%s\n", mPending.front().Data());
    if(ret < 0 || ferror(mPipe)) {
      throw( Operator::Exception(this, Operator::OE_Break, "write error") );
    }
    mPending.pop_front();
  }
}


/**************************************************************************/

#include "PipeEventor.c7"
 PipeEventor.cxx:1
 PipeEventor.cxx:2
 PipeEventor.cxx:3
 PipeEventor.cxx:4
 PipeEventor.cxx:5
 PipeEventor.cxx:6
 PipeEventor.cxx:7
 PipeEventor.cxx:8
 PipeEventor.cxx:9
 PipeEventor.cxx:10
 PipeEventor.cxx:11
 PipeEventor.cxx:12
 PipeEventor.cxx:13
 PipeEventor.cxx:14
 PipeEventor.cxx:15
 PipeEventor.cxx:16
 PipeEventor.cxx:17
 PipeEventor.cxx:18
 PipeEventor.cxx:19
 PipeEventor.cxx:20
 PipeEventor.cxx:21
 PipeEventor.cxx:22
 PipeEventor.cxx:23
 PipeEventor.cxx:24
 PipeEventor.cxx:25
 PipeEventor.cxx:26
 PipeEventor.cxx:27
 PipeEventor.cxx:28
 PipeEventor.cxx:29
 PipeEventor.cxx:30
 PipeEventor.cxx:31
 PipeEventor.cxx:32
 PipeEventor.cxx:33
 PipeEventor.cxx:34
 PipeEventor.cxx:35
 PipeEventor.cxx:36
 PipeEventor.cxx:37
 PipeEventor.cxx:38
 PipeEventor.cxx:39
 PipeEventor.cxx:40
 PipeEventor.cxx:41
 PipeEventor.cxx:42
 PipeEventor.cxx:43
 PipeEventor.cxx:44
 PipeEventor.cxx:45
 PipeEventor.cxx:46
 PipeEventor.cxx:47
 PipeEventor.cxx:48
 PipeEventor.cxx:49
 PipeEventor.cxx:50
 PipeEventor.cxx:51
 PipeEventor.cxx:52
 PipeEventor.cxx:53
 PipeEventor.cxx:54
 PipeEventor.cxx:55
 PipeEventor.cxx:56
 PipeEventor.cxx:57
 PipeEventor.cxx:58
 PipeEventor.cxx:59
 PipeEventor.cxx:60
 PipeEventor.cxx:61
 PipeEventor.cxx:62
 PipeEventor.cxx:63
 PipeEventor.cxx:64
 PipeEventor.cxx:65
 PipeEventor.cxx:66
 PipeEventor.cxx:67
 PipeEventor.cxx:68
 PipeEventor.cxx:69
 PipeEventor.cxx:70
 PipeEventor.cxx:71
 PipeEventor.cxx:72
 PipeEventor.cxx:73
 PipeEventor.cxx:74
 PipeEventor.cxx:75
 PipeEventor.cxx:76
 PipeEventor.cxx:77
 PipeEventor.cxx:78
 PipeEventor.cxx:79
 PipeEventor.cxx:80
 PipeEventor.cxx:81
 PipeEventor.cxx:82
 PipeEventor.cxx:83
 PipeEventor.cxx:84
 PipeEventor.cxx:85
 PipeEventor.cxx:86
 PipeEventor.cxx:87
 PipeEventor.cxx:88
 PipeEventor.cxx:89
 PipeEventor.cxx:90
 PipeEventor.cxx:91
 PipeEventor.cxx:92
 PipeEventor.cxx:93
 PipeEventor.cxx:94
 PipeEventor.cxx:95
 PipeEventor.cxx:96
 PipeEventor.cxx:97
 PipeEventor.cxx:98
 PipeEventor.cxx:99
 PipeEventor.cxx:100
 PipeEventor.cxx:101
 PipeEventor.cxx:102
 PipeEventor.cxx:103
 PipeEventor.cxx:104
 PipeEventor.cxx:105
 PipeEventor.cxx:106
 PipeEventor.cxx:107
 PipeEventor.cxx:108
 PipeEventor.cxx:109
 PipeEventor.cxx:110
 PipeEventor.cxx:111
 PipeEventor.cxx:112
 PipeEventor.cxx:113
 PipeEventor.cxx:114
 PipeEventor.cxx:115
 PipeEventor.cxx:116
 PipeEventor.cxx:117
 PipeEventor.cxx:118
 PipeEventor.cxx:119
 PipeEventor.cxx:120
 PipeEventor.cxx:121
 PipeEventor.cxx:122
 PipeEventor.cxx:123
 PipeEventor.cxx:124
 PipeEventor.cxx:125
 PipeEventor.cxx:126
 PipeEventor.cxx:127
 PipeEventor.cxx:128
 PipeEventor.cxx:129