90 class TGWin32CallBackObject : 
public TObject {
 
   92    TGWin32CallBack   fCallBack;  
 
   95    TGWin32CallBackObject(TGWin32CallBack cb,
void *p):fCallBack(cb),fParam(p) {}
 
   96    ~TGWin32CallBackObject() { 
if (fParam) 
delete fParam; }
 
  100 class TGWin32ProxyBasePrivate {
 
  103    TGWin32ProxyBasePrivate();
 
  104    ~TGWin32ProxyBasePrivate();
 
  110 TGWin32ProxyBasePrivate::TGWin32ProxyBasePrivate()
 
  112    fEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
 
  118 TGWin32ProxyBasePrivate::~TGWin32ProxyBasePrivate()
 
  120    if (fEvent) ::CloseHandle(fEvent);
 
  125 ULong_t TGWin32ProxyBase::fgPostMessageId = 0;
 
  126 ULong_t TGWin32ProxyBase::fgPingMessageId = 0;
 
  127 ULong_t TGWin32ProxyBase::fgMainThreadId = 0;
 
  128 ULong_t TGWin32ProxyBase::fgUserThreadId = 0;
 
  129 Long_t  TGWin32ProxyBase::fgLock = 0;
 
  130 UInt_t  TGWin32ProxyBase::fMaxResponseTime = 0;
 
  136 TGWin32ProxyBase::TGWin32ProxyBase()
 
  138    fIsVirtualX = kFALSE;
 
  141    fListOfCallBacks = 
new TList();
 
  143    fId = ::GetCurrentThreadId();
 
  144    fPimpl = 
new TGWin32ProxyBasePrivate();
 
  146    if (!fgPostMessageId) fgPostMessageId = ::RegisterWindowMessage(
"TGWin32ProxyBase::Post");
 
  147    if (!fgPingMessageId) fgPingMessageId = ::RegisterWindowMessage(
"TGWin32ProxyBase::Ping");
 
  153 TGWin32ProxyBase::~TGWin32ProxyBase()
 
  155    fListOfCallBacks->Delete();
 
  156    delete fListOfCallBacks;
 
  157    fListOfCallBacks = 0;
 
  165 void TGWin32ProxyBase::Lock()
 
  173 void TGWin32ProxyBase::Unlock()
 
  181 void TGWin32ProxyBase::GlobalLock()
 
  183    if (IsGloballyLocked()) 
return;
 
  184    ::InterlockedIncrement(&fgLock);
 
  190 void TGWin32ProxyBase::GlobalUnlock()
 
  192    if (!IsGloballyLocked()) 
return;
 
  193    ::InterlockedDecrement(&fgLock);
 
  199 Bool_t TGWin32ProxyBase::Ping()
 
  201    return ::PostThreadMessage(fgMainThreadId, fgPingMessageId, (WPARAM)0, 0L);
 
  207 Double_t TGWin32ProxyBase::GetMilliSeconds()
 
  209    static LARGE_INTEGER freq;
 
  210    static Bool_t first = kTRUE;
 
  212    static Double_t overhead = 0;
 
  215       LARGE_INTEGER count0;
 
  216       ::QueryPerformanceFrequency(&freq);
 
  217       ::QueryPerformanceCounter(&count0);
 
  220          dummy = ((Double_t)count0.QuadPart - overhead)*1000./((Double_t)freq.QuadPart);
 
  222       ::QueryPerformanceCounter(&count);
 
  223       overhead = (Double_t)count.QuadPart - (Double_t)count0.QuadPart;
 
  227    ::QueryPerformanceCounter(&count);
 
  228    return ((Double_t)count.QuadPart - overhead)*1000./((Double_t)freq.QuadPart);
 
  235 void TGWin32ProxyBase::ExecuteCallBack(Bool_t sync)
 
  238    if (fListOfCallBacks && fListOfCallBacks->GetSize()) {
 
  239       TIter next(fListOfCallBacks);
 
  240       TGWin32CallBackObject *obj;
 
  242       while ((obj = (TGWin32CallBackObject*)next())) {
 
  243          obj->fCallBack(obj->fParam);  
 
  247       if (fCallBack) fCallBack(fParam);
 
  248       ::SetEvent(fPimpl->fEvent);
 
  262 Bool_t TGWin32ProxyBase::ForwardCallBack(Bool_t sync)
 
  266    if (!fgMainThreadId) 
return kFALSE;
 
  268    while (IsGloballyLocked()) {
 
  270 #ifdef OLD_THREAD_IMPLEMENTATION 
  271       if (GetCurrentThreadId() == fgMainThreadId)
 
  275       if (!fgMainThreadId) 
return kFALSE; 
 
  278    Bool_t batch = !sync && (fListOfCallBacks->GetSize() < fBatchLimit);
 
  282    if (!fgUserThreadId && fIsVirtualX &&
 
  283        (GetCurrentThreadId() != fgMainThreadId) &&
 
  284        (fListOfCallBacks->GetSize() < fBatchLimit))
 
  288       fListOfCallBacks->Add(
new TGWin32CallBackObject(fCallBack, fParam));
 
  292    while (!::PostThreadMessage(fgMainThreadId, fgPostMessageId, (WPARAM)
this, 0L)) {
 
  295       if (wait++ > 5) 
return kFALSE; 
 
  298 #ifdef OLD_THREAD_IMPLEMENTATION 
  302    DWORD res = WAIT_TIMEOUT;
 
  303    while (res ==  WAIT_TIMEOUT) {
 
  304       res = ::WaitForSingleObject(fPimpl->fEvent, 100);
 
  305 #ifdef OLD_THREAD_IMPLEMENTATION 
  306       if ((GetCurrentThreadId() == fgMainThreadId) ||
 
  307          (!gROOT->IsLineProcessing() && IsGloballyLocked())) {
 
  310       if (cnt++ > 20) 
break; 
 
  313    ::ResetEvent(fPimpl->fEvent);
 
  315    if (res == WAIT_TIMEOUT) { 
 
  320    fListOfCallBacks->Delete();
 
  327 Bool_t TGWin32ProxyBase::IsGloballyLocked()
 
  335 void TGWin32ProxyBase::SendExitMessage()
 
  337    ::PostThreadMessage(fgMainThreadId, WM_QUIT, 0, 0L);