ROOT logo
// $Id: TRootXTReq.cxx 2650 2012-01-21 03:52:35Z 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/.

#include "TRootXTReq.h"

#include <Gled/GCondition.h>
#include <Gled/GThread.h>

#include <TSystem.h>
#include <TTimer.h>

// TRootXTReq

//______________________________________________________________________________
//
//

ClassImp(TRootXTReq);

list<TRootXTReq*>  TRootXTReq::sQueue;
GThread           *TRootXTReq::sRootThread = 0;
GMutex            *TRootXTReq::sQueueMutex = 0;
bool               TRootXTReq::sSheduled   = false;


//==============================================================================

TRootXTReq::TRootXTReq(const char* n) :
  m_return_condition(0),
  mName(n)
{}

TRootXTReq::~TRootXTReq()
{
  delete m_return_condition;
}

//------------------------------------------------------------------------------

void TRootXTReq::post_request()
{
  GMutexHolder _lck(*sQueueMutex);

  sQueue.push_back(this);

  if ( ! sSheduled)
  {
    sSheduled = true;
    sRootThread->Kill(GThread::SigUSR1);
  }
}

void TRootXTReq::ShootRequest()
{
  // Places request into the queue and requests execution in RootApp thread.
  // It returns immediately after that, without waiting for execution.
  // The request is deleted after execution.

  if (m_return_condition)
  {
    delete m_return_condition;
    m_return_condition = 0;
  }

  post_request();
}

void TRootXTReq::ShootRequestAndWait()
{
  // Places request into the queue, requests execution in RootApp thread and
  // waits for the execution to be completed.
  // The request is not deleted after execution as it might carry return
  // value.
  // The same request can be reused several times.

  if (!m_return_condition)
    m_return_condition = new GCondition;

  m_return_condition->Lock();

  post_request();

  m_return_condition->Wait();
  m_return_condition->Unlock();
}


//==============================================================================

namespace
{
  class XTReqTimer : public TTimer
  {
  public:
    XTReqTimer() : TTimer() {}
    virtual ~XTReqTimer() {}

    void FireAway()
    {
      Reset();
      gSystem->AddTimer(this);
    }

    virtual Bool_t Notify()
    {
      gSystem->RemoveTimer(this);
      TRootXTReq::ProcessQueue();
      return kTRUE;
    }
  };

  XTReqTimer l_xtreq_timer;

  void l_sigusr1_handler(GSignal*)
  {
    ISdebug(1, "RootApp thread Usr1 signal handler -- firing timer for XT requests.");
    l_xtreq_timer.FireAway();
  }
};

//------------------------------------------------------------------------------

void TRootXTReq::Bootstrap(GThread* root_thread)
{
  // Should be called from the RootApp thread.

  static const Exc_t _eh("TRootXTReq::Bootstrap ");

  if (sRootThread != 0)
    throw _eh + "Already initialized.";

  sRootThread = root_thread;
  sQueueMutex = new GMutex(GMutex::recursive);

  GThread::SetSignalHandler(GThread::SigUSR1, l_sigusr1_handler);
}

void TRootXTReq::Shutdown()
{
  static const Exc_t _eh("TRootXTReq::Shutdown ");

  if (sRootThread == 0)
    throw _eh + "Have not beem initialized.";

  // Should lock and drain queue ... or sth.

  sRootThread = 0;
  GThread::SetSignalHandler(GThread::SigUSR1, 0);
  delete sQueueMutex; sQueueMutex = 0;
}

void TRootXTReq::ProcessQueue()
{
  ISdebug(1, "TRootXTReq::ProcessQueue Timer fired, processing queue.");

  while (true)
  {
    TRootXTReq *req = 0;
    {
      GMutexHolder _lck(*sQueueMutex);

      if ( ! sQueue.empty())
      {
	req = sQueue.front();
	sQueue.pop_front();
      }
      else
      {
	sSheduled = false;
	break;
      }
    }

    req->Act();

    if (req->m_return_condition)
    {
      req->m_return_condition->LockSignal();
    }
    else
    {
      delete req;
    }
  }
}
 TRootXTReq.cxx:1
 TRootXTReq.cxx:2
 TRootXTReq.cxx:3
 TRootXTReq.cxx:4
 TRootXTReq.cxx:5
 TRootXTReq.cxx:6
 TRootXTReq.cxx:7
 TRootXTReq.cxx:8
 TRootXTReq.cxx:9
 TRootXTReq.cxx:10
 TRootXTReq.cxx:11
 TRootXTReq.cxx:12
 TRootXTReq.cxx:13
 TRootXTReq.cxx:14
 TRootXTReq.cxx:15
 TRootXTReq.cxx:16
 TRootXTReq.cxx:17
 TRootXTReq.cxx:18
 TRootXTReq.cxx:19
 TRootXTReq.cxx:20
 TRootXTReq.cxx:21
 TRootXTReq.cxx:22
 TRootXTReq.cxx:23
 TRootXTReq.cxx:24
 TRootXTReq.cxx:25
 TRootXTReq.cxx:26
 TRootXTReq.cxx:27
 TRootXTReq.cxx:28
 TRootXTReq.cxx:29
 TRootXTReq.cxx:30
 TRootXTReq.cxx:31
 TRootXTReq.cxx:32
 TRootXTReq.cxx:33
 TRootXTReq.cxx:34
 TRootXTReq.cxx:35
 TRootXTReq.cxx:36
 TRootXTReq.cxx:37
 TRootXTReq.cxx:38
 TRootXTReq.cxx:39
 TRootXTReq.cxx:40
 TRootXTReq.cxx:41
 TRootXTReq.cxx:42
 TRootXTReq.cxx:43
 TRootXTReq.cxx:44
 TRootXTReq.cxx:45
 TRootXTReq.cxx:46
 TRootXTReq.cxx:47
 TRootXTReq.cxx:48
 TRootXTReq.cxx:49
 TRootXTReq.cxx:50
 TRootXTReq.cxx:51
 TRootXTReq.cxx:52
 TRootXTReq.cxx:53
 TRootXTReq.cxx:54
 TRootXTReq.cxx:55
 TRootXTReq.cxx:56
 TRootXTReq.cxx:57
 TRootXTReq.cxx:58
 TRootXTReq.cxx:59
 TRootXTReq.cxx:60
 TRootXTReq.cxx:61
 TRootXTReq.cxx:62
 TRootXTReq.cxx:63
 TRootXTReq.cxx:64
 TRootXTReq.cxx:65
 TRootXTReq.cxx:66
 TRootXTReq.cxx:67
 TRootXTReq.cxx:68
 TRootXTReq.cxx:69
 TRootXTReq.cxx:70
 TRootXTReq.cxx:71
 TRootXTReq.cxx:72
 TRootXTReq.cxx:73
 TRootXTReq.cxx:74
 TRootXTReq.cxx:75
 TRootXTReq.cxx:76
 TRootXTReq.cxx:77
 TRootXTReq.cxx:78
 TRootXTReq.cxx:79
 TRootXTReq.cxx:80
 TRootXTReq.cxx:81
 TRootXTReq.cxx:82
 TRootXTReq.cxx:83
 TRootXTReq.cxx:84
 TRootXTReq.cxx:85
 TRootXTReq.cxx:86
 TRootXTReq.cxx:87
 TRootXTReq.cxx:88
 TRootXTReq.cxx:89
 TRootXTReq.cxx:90
 TRootXTReq.cxx:91
 TRootXTReq.cxx:92
 TRootXTReq.cxx:93
 TRootXTReq.cxx:94
 TRootXTReq.cxx:95
 TRootXTReq.cxx:96
 TRootXTReq.cxx:97
 TRootXTReq.cxx:98
 TRootXTReq.cxx:99
 TRootXTReq.cxx:100
 TRootXTReq.cxx:101
 TRootXTReq.cxx:102
 TRootXTReq.cxx:103
 TRootXTReq.cxx:104
 TRootXTReq.cxx:105
 TRootXTReq.cxx:106
 TRootXTReq.cxx:107
 TRootXTReq.cxx:108
 TRootXTReq.cxx:109
 TRootXTReq.cxx:110
 TRootXTReq.cxx:111
 TRootXTReq.cxx:112
 TRootXTReq.cxx:113
 TRootXTReq.cxx:114
 TRootXTReq.cxx:115
 TRootXTReq.cxx:116
 TRootXTReq.cxx:117
 TRootXTReq.cxx:118
 TRootXTReq.cxx:119
 TRootXTReq.cxx:120
 TRootXTReq.cxx:121
 TRootXTReq.cxx:122
 TRootXTReq.cxx:123
 TRootXTReq.cxx:124
 TRootXTReq.cxx:125
 TRootXTReq.cxx:126
 TRootXTReq.cxx:127
 TRootXTReq.cxx:128
 TRootXTReq.cxx:129
 TRootXTReq.cxx:130
 TRootXTReq.cxx:131
 TRootXTReq.cxx:132
 TRootXTReq.cxx:133
 TRootXTReq.cxx:134
 TRootXTReq.cxx:135
 TRootXTReq.cxx:136
 TRootXTReq.cxx:137
 TRootXTReq.cxx:138
 TRootXTReq.cxx:139
 TRootXTReq.cxx:140
 TRootXTReq.cxx:141
 TRootXTReq.cxx:142
 TRootXTReq.cxx:143
 TRootXTReq.cxx:144
 TRootXTReq.cxx:145
 TRootXTReq.cxx:146
 TRootXTReq.cxx:147
 TRootXTReq.cxx:148
 TRootXTReq.cxx:149
 TRootXTReq.cxx:150
 TRootXTReq.cxx:151
 TRootXTReq.cxx:152
 TRootXTReq.cxx:153
 TRootXTReq.cxx:154
 TRootXTReq.cxx:155
 TRootXTReq.cxx:156
 TRootXTReq.cxx:157
 TRootXTReq.cxx:158
 TRootXTReq.cxx:159
 TRootXTReq.cxx:160
 TRootXTReq.cxx:161
 TRootXTReq.cxx:162
 TRootXTReq.cxx:163
 TRootXTReq.cxx:164
 TRootXTReq.cxx:165
 TRootXTReq.cxx:166
 TRootXTReq.cxx:167
 TRootXTReq.cxx:168
 TRootXTReq.cxx:169
 TRootXTReq.cxx:170
 TRootXTReq.cxx:171
 TRootXTReq.cxx:172
 TRootXTReq.cxx:173
 TRootXTReq.cxx:174
 TRootXTReq.cxx:175
 TRootXTReq.cxx:176
 TRootXTReq.cxx:177
 TRootXTReq.cxx:178
 TRootXTReq.cxx:179
 TRootXTReq.cxx:180
 TRootXTReq.cxx:181
 TRootXTReq.cxx:182
 TRootXTReq.cxx:183
 TRootXTReq.cxx:184
 TRootXTReq.cxx:185
 TRootXTReq.cxx:186
 TRootXTReq.cxx:187
 TRootXTReq.cxx:188