File indexing completed on 2024-04-06 12:11:44
0001
0002 #include "Fireworks/Core/interface/TRootXTReq.h"
0003
0004 #include "TCondition.h"
0005 #include "TThread.h"
0006 #include "TMutex.h"
0007 #include <TSysEvtHandler.h>
0008 #include <TSystem.h>
0009 #include <TTimer.h>
0010
0011
0012 #include <csignal>
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 TRootXTReq::lpXTReq_t TRootXTReq::sQueue;
0041 pthread_t TRootXTReq::sRootThread = 0;
0042 TMutex *TRootXTReq::sQueueMutex = nullptr;
0043 TSignalHandler *TRootXTReq::sSigHandler = nullptr;
0044 bool TRootXTReq::sSheduled = false;
0045
0046
0047
0048 TRootXTReq::TRootXTReq(const char *n) : m_return_condition(nullptr), mName(n) {}
0049
0050 TRootXTReq::~TRootXTReq() { delete m_return_condition; }
0051
0052
0053
0054 void TRootXTReq::post_request() {
0055 TLockGuard _lck(sQueueMutex);
0056
0057 sQueue.push_back(this);
0058
0059 if (!sSheduled) {
0060 sSheduled = true;
0061 pthread_kill(sRootThread, SIGUSR1);
0062 }
0063 }
0064
0065 void TRootXTReq::ShootRequest() {
0066
0067
0068
0069
0070 if (m_return_condition) {
0071 delete m_return_condition;
0072 m_return_condition = nullptr;
0073 }
0074
0075 post_request();
0076 }
0077
0078 void TRootXTReq::ShootRequestAndWait() {
0079
0080
0081
0082
0083
0084
0085 if (!m_return_condition)
0086 m_return_condition = new TCondition;
0087
0088 m_return_condition->GetMutex()->Lock();
0089
0090 post_request();
0091
0092 m_return_condition->Wait();
0093 m_return_condition->GetMutex()->UnLock();
0094 }
0095
0096
0097
0098 class RootSig2XTReqHandler : public TSignalHandler {
0099 private:
0100 class XTReqTimer : public TTimer {
0101 public:
0102 XTReqTimer() : TTimer() {}
0103 ~XTReqTimer() override {}
0104
0105 void FireAway() {
0106 Reset();
0107 gSystem->AddTimer(this);
0108 }
0109
0110 Bool_t Notify() override {
0111 gSystem->RemoveTimer(this);
0112 TRootXTReq::ProcessQueue();
0113 return kTRUE;
0114 }
0115 };
0116
0117 XTReqTimer mTimer;
0118
0119 public:
0120 RootSig2XTReqHandler() : TSignalHandler(kSigUser1), mTimer() { Add(); }
0121 ~RootSig2XTReqHandler() override {}
0122
0123 Bool_t Notify() override {
0124 printf("Usr1 Woof Woof in Root thread! Starting Timer.\n");
0125 mTimer.FireAway();
0126 return kTRUE;
0127 }
0128 };
0129
0130
0131
0132 void TRootXTReq::Bootstrap(pthread_t root_thread) {
0133 static const TString _eh("TRootXTReq::Bootstrap ");
0134
0135 if (sRootThread != 0)
0136 throw _eh + "Already initialized.";
0137
0138 sRootThread = root_thread;
0139 sQueueMutex = new TMutex(kTRUE);
0140 sSigHandler = new RootSig2XTReqHandler;
0141 }
0142
0143 void TRootXTReq::Shutdown() {
0144 static const TString _eh("TRootXTReq::Shutdown ");
0145
0146 if (sRootThread == 0)
0147 throw _eh + "Have not beem initialized.";
0148
0149
0150
0151 sRootThread = 0;
0152 delete sSigHandler;
0153 sSigHandler = nullptr;
0154 delete sQueueMutex;
0155 sQueueMutex = nullptr;
0156 }
0157
0158 void TRootXTReq::ProcessQueue() {
0159 printf("Timer fired, processing queue.\n");
0160
0161 while (true) {
0162 TRootXTReq *req = nullptr;
0163 {
0164 TLockGuard _lck(sQueueMutex);
0165
0166 if (!sQueue.empty()) {
0167 req = sQueue.front();
0168 sQueue.pop_front();
0169 } else {
0170 sSheduled = false;
0171 break;
0172 }
0173 }
0174
0175 req->Act();
0176
0177 if (req->m_return_condition) {
0178 req->m_return_condition->GetMutex()->Lock();
0179 req->m_return_condition->Signal();
0180 req->m_return_condition->GetMutex()->UnLock();
0181 } else {
0182 delete req;
0183 }
0184 }
0185 }