ROOT logo
// $Id: XrdFileCloseReporter.cxx 2819 2012-07-13 02:56:44Z 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 "XrdFileCloseReporter.h"
#include "Glasses/ZLog.h"
#include "XrdFileCloseReporter.c7"

#include "XrdFile.h"
#include "XrdUser.h"
#include "XrdServer.h"

#include "Gled/GThread.h"

// XrdFileCloseReporter

//______________________________________________________________________________
//
//

ClassImp(XrdFileCloseReporter);

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

void XrdFileCloseReporter::_init()
{
  mCondWaitSec = 0;
  mNProcessed = mNQueued = 0;
  bRunning = false;
}

XrdFileCloseReporter::XrdFileCloseReporter(const Text_t* n, const Text_t* t) :
  ZGlass(n, t),
  mReporterThread(0)
{
  _init();
}

XrdFileCloseReporter::~XrdFileCloseReporter()
{}

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

void XrdFileCloseReporter::FileClosed(XrdFile* file, XrdUser* user, XrdServer* server)
{
  // Put the triplet into queue and signal condition.

  if (! bRunning)
    return;

  file  ->IncEyeRefCount();
  user  ->IncEyeRefCount();
  server->IncEyeRefCount();

  GMutexHolder _lck(mReporterCond);
  mReporterQueue.push_back(FileUserServer(file, user, server));
  ++mNQueued;
  mReporterCond.Signal();
}

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

void XrdFileCloseReporter::ReportLoopInit()
{
  // Sub-classes should override this to perform one-time initialization.
  // This virtual is called from the startup-handler of the worker thread.
  // No need to call the parent-class implementation there.
}

void XrdFileCloseReporter::ReportFileClosed(FileUserServer& fus)
{
  // Sub-classes should override this to process files that have been just
  // closed. No need to call the parent-class implementation from there, here
  // we just write out to the log.

  static const Exc_t _eh("XrdFileCloseReporter::ReportFileClosed ");

  ZLog::Helper log(*mLog, ZLog::L_Message, _eh);
  log.Form("LFN=%s", fus.fFile->GetName());
}

void XrdFileCloseReporter::ReportCondWaitTimeout()
{
  // Sub-classes should override this to perform periodic checks.
  // If mCondWaitSec = 0 then this function never gets called.
}

void XrdFileCloseReporter::ReportLoopFinalize()
{
  // Sub-classes should override this to perform cleanup.
  // This virtual is called from the cleanup-handler of the worker thread.
  // No need to call the parent-class implementation there.
}

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

void* XrdFileCloseReporter::tl_ReportLoop(XrdFileCloseReporter* r)
{
  GThread *thr = GThread::Self();

  r->mSaturn->register_detached_thread(r, thr);

  thr->CleanupPush((GThread_cu_foo) cu_ReportLoop, r);

  {
    GLensReadHolder _lck(r);
    r->bRunning = true;
    r->Stamp(r->FID());
  }

  r->ReportLoopInit();

  r->ReportLoop();

  return 0;
}

void XrdFileCloseReporter::cu_ReportLoop(XrdFileCloseReporter* r)
{
  r->ReportLoopFinalize();

  r->mSaturn->unregister_detached_thread(r, GThread::Self());

  {
    GLensReadHolder _lck(r);
    r->bRunning = false;
  }

  r->DrainQueue();

  {
    GLensReadHolder _lck(r);
    r->mReporterThread = 0;
    r->Stamp(r->FID());
  }
}

void XrdFileCloseReporter::ReportLoop()
{
  static const Exc_t _eh("XrdFileCloseReporter::ReportLoop ");

  while (true)
  {
    FileUserServer fus;
    {
      GMutexHolder _lck(mReporterCond);
      if (mReporterQueue.empty())
      {
	if (mCondWaitSec <= 0)
	{
	  mReporterCond.Wait();
	}
	else
	{
	  if (mReporterCond.TimedWaitUntil(GTime::ApproximateTime() + GTime(mCondWaitSec)) == 1)
	  {
	    ReportCondWaitTimeout();
	    continue;
	  }
	}
      }
      fus = mReporterQueue.front();
      mReporterQueue.pop_front();
      --mNQueued;
    }

    ReportFileClosed(fus);
    ++mNProcessed;

    fus.fFile  ->DecEyeRefCount();
    fus.fUser  ->DecEyeRefCount();
    fus.fServer->DecEyeRefCount();
  }
}

void XrdFileCloseReporter::DrainQueue()
{
  GMutexHolder _lck(mReporterCond);
  while (! mReporterQueue.empty())
  {
    FileUserServer fus = mReporterQueue.front();
    fus.fFile  ->DecEyeRefCount();
    fus.fUser  ->DecEyeRefCount();
    fus.fServer->DecEyeRefCount();
    mReporterQueue.pop_front();
  }
  mNQueued = 0;
}

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

void XrdFileCloseReporter::StartReporter()
{
  static const Exc_t _eh("XrdFileCloseReporter::StartReporter ");

  {
    GLensReadHolder _lck(this);
    if (mReporterThread)
      throw _eh + "already running.";

    mReporterThread = new GThread("XrdFileCloseReporter-Reporter",
                                  (GThread_foo) tl_ReportLoop, this,
                                  false);
  }
  mReporterThread->SetNice(20);
  mReporterThread->Spawn();
}

void XrdFileCloseReporter::StopReporter()
{
  static const Exc_t _eh("XrdFileCloseReporter::StopReporter ");

  GThread *thr = 0;
  {
    GLensReadHolder _lck(this);
    if ( ! GThread::IsValidPtr(mReporterThread))
      throw _eh + "not running.";
    thr = mReporterThread;
    GThread::InvalidatePtr(mReporterThread);
  }
  thr->Cancel();
  thr->Join();
}
 XrdFileCloseReporter.cxx:1
 XrdFileCloseReporter.cxx:2
 XrdFileCloseReporter.cxx:3
 XrdFileCloseReporter.cxx:4
 XrdFileCloseReporter.cxx:5
 XrdFileCloseReporter.cxx:6
 XrdFileCloseReporter.cxx:7
 XrdFileCloseReporter.cxx:8
 XrdFileCloseReporter.cxx:9
 XrdFileCloseReporter.cxx:10
 XrdFileCloseReporter.cxx:11
 XrdFileCloseReporter.cxx:12
 XrdFileCloseReporter.cxx:13
 XrdFileCloseReporter.cxx:14
 XrdFileCloseReporter.cxx:15
 XrdFileCloseReporter.cxx:16
 XrdFileCloseReporter.cxx:17
 XrdFileCloseReporter.cxx:18
 XrdFileCloseReporter.cxx:19
 XrdFileCloseReporter.cxx:20
 XrdFileCloseReporter.cxx:21
 XrdFileCloseReporter.cxx:22
 XrdFileCloseReporter.cxx:23
 XrdFileCloseReporter.cxx:24
 XrdFileCloseReporter.cxx:25
 XrdFileCloseReporter.cxx:26
 XrdFileCloseReporter.cxx:27
 XrdFileCloseReporter.cxx:28
 XrdFileCloseReporter.cxx:29
 XrdFileCloseReporter.cxx:30
 XrdFileCloseReporter.cxx:31
 XrdFileCloseReporter.cxx:32
 XrdFileCloseReporter.cxx:33
 XrdFileCloseReporter.cxx:34
 XrdFileCloseReporter.cxx:35
 XrdFileCloseReporter.cxx:36
 XrdFileCloseReporter.cxx:37
 XrdFileCloseReporter.cxx:38
 XrdFileCloseReporter.cxx:39
 XrdFileCloseReporter.cxx:40
 XrdFileCloseReporter.cxx:41
 XrdFileCloseReporter.cxx:42
 XrdFileCloseReporter.cxx:43
 XrdFileCloseReporter.cxx:44
 XrdFileCloseReporter.cxx:45
 XrdFileCloseReporter.cxx:46
 XrdFileCloseReporter.cxx:47
 XrdFileCloseReporter.cxx:48
 XrdFileCloseReporter.cxx:49
 XrdFileCloseReporter.cxx:50
 XrdFileCloseReporter.cxx:51
 XrdFileCloseReporter.cxx:52
 XrdFileCloseReporter.cxx:53
 XrdFileCloseReporter.cxx:54
 XrdFileCloseReporter.cxx:55
 XrdFileCloseReporter.cxx:56
 XrdFileCloseReporter.cxx:57
 XrdFileCloseReporter.cxx:58
 XrdFileCloseReporter.cxx:59
 XrdFileCloseReporter.cxx:60
 XrdFileCloseReporter.cxx:61
 XrdFileCloseReporter.cxx:62
 XrdFileCloseReporter.cxx:63
 XrdFileCloseReporter.cxx:64
 XrdFileCloseReporter.cxx:65
 XrdFileCloseReporter.cxx:66
 XrdFileCloseReporter.cxx:67
 XrdFileCloseReporter.cxx:68
 XrdFileCloseReporter.cxx:69
 XrdFileCloseReporter.cxx:70
 XrdFileCloseReporter.cxx:71
 XrdFileCloseReporter.cxx:72
 XrdFileCloseReporter.cxx:73
 XrdFileCloseReporter.cxx:74
 XrdFileCloseReporter.cxx:75
 XrdFileCloseReporter.cxx:76
 XrdFileCloseReporter.cxx:77
 XrdFileCloseReporter.cxx:78
 XrdFileCloseReporter.cxx:79
 XrdFileCloseReporter.cxx:80
 XrdFileCloseReporter.cxx:81
 XrdFileCloseReporter.cxx:82
 XrdFileCloseReporter.cxx:83
 XrdFileCloseReporter.cxx:84
 XrdFileCloseReporter.cxx:85
 XrdFileCloseReporter.cxx:86
 XrdFileCloseReporter.cxx:87
 XrdFileCloseReporter.cxx:88
 XrdFileCloseReporter.cxx:89
 XrdFileCloseReporter.cxx:90
 XrdFileCloseReporter.cxx:91
 XrdFileCloseReporter.cxx:92
 XrdFileCloseReporter.cxx:93
 XrdFileCloseReporter.cxx:94
 XrdFileCloseReporter.cxx:95
 XrdFileCloseReporter.cxx:96
 XrdFileCloseReporter.cxx:97
 XrdFileCloseReporter.cxx:98
 XrdFileCloseReporter.cxx:99
 XrdFileCloseReporter.cxx:100
 XrdFileCloseReporter.cxx:101
 XrdFileCloseReporter.cxx:102
 XrdFileCloseReporter.cxx:103
 XrdFileCloseReporter.cxx:104
 XrdFileCloseReporter.cxx:105
 XrdFileCloseReporter.cxx:106
 XrdFileCloseReporter.cxx:107
 XrdFileCloseReporter.cxx:108
 XrdFileCloseReporter.cxx:109
 XrdFileCloseReporter.cxx:110
 XrdFileCloseReporter.cxx:111
 XrdFileCloseReporter.cxx:112
 XrdFileCloseReporter.cxx:113
 XrdFileCloseReporter.cxx:114
 XrdFileCloseReporter.cxx:115
 XrdFileCloseReporter.cxx:116
 XrdFileCloseReporter.cxx:117
 XrdFileCloseReporter.cxx:118
 XrdFileCloseReporter.cxx:119
 XrdFileCloseReporter.cxx:120
 XrdFileCloseReporter.cxx:121
 XrdFileCloseReporter.cxx:122
 XrdFileCloseReporter.cxx:123
 XrdFileCloseReporter.cxx:124
 XrdFileCloseReporter.cxx:125
 XrdFileCloseReporter.cxx:126
 XrdFileCloseReporter.cxx:127
 XrdFileCloseReporter.cxx:128
 XrdFileCloseReporter.cxx:129
 XrdFileCloseReporter.cxx:130
 XrdFileCloseReporter.cxx:131
 XrdFileCloseReporter.cxx:132
 XrdFileCloseReporter.cxx:133
 XrdFileCloseReporter.cxx:134
 XrdFileCloseReporter.cxx:135
 XrdFileCloseReporter.cxx:136
 XrdFileCloseReporter.cxx:137
 XrdFileCloseReporter.cxx:138
 XrdFileCloseReporter.cxx:139
 XrdFileCloseReporter.cxx:140
 XrdFileCloseReporter.cxx:141
 XrdFileCloseReporter.cxx:142
 XrdFileCloseReporter.cxx:143
 XrdFileCloseReporter.cxx:144
 XrdFileCloseReporter.cxx:145
 XrdFileCloseReporter.cxx:146
 XrdFileCloseReporter.cxx:147
 XrdFileCloseReporter.cxx:148
 XrdFileCloseReporter.cxx:149
 XrdFileCloseReporter.cxx:150
 XrdFileCloseReporter.cxx:151
 XrdFileCloseReporter.cxx:152
 XrdFileCloseReporter.cxx:153
 XrdFileCloseReporter.cxx:154
 XrdFileCloseReporter.cxx:155
 XrdFileCloseReporter.cxx:156
 XrdFileCloseReporter.cxx:157
 XrdFileCloseReporter.cxx:158
 XrdFileCloseReporter.cxx:159
 XrdFileCloseReporter.cxx:160
 XrdFileCloseReporter.cxx:161
 XrdFileCloseReporter.cxx:162
 XrdFileCloseReporter.cxx:163
 XrdFileCloseReporter.cxx:164
 XrdFileCloseReporter.cxx:165
 XrdFileCloseReporter.cxx:166
 XrdFileCloseReporter.cxx:167
 XrdFileCloseReporter.cxx:168
 XrdFileCloseReporter.cxx:169
 XrdFileCloseReporter.cxx:170
 XrdFileCloseReporter.cxx:171
 XrdFileCloseReporter.cxx:172
 XrdFileCloseReporter.cxx:173
 XrdFileCloseReporter.cxx:174
 XrdFileCloseReporter.cxx:175
 XrdFileCloseReporter.cxx:176
 XrdFileCloseReporter.cxx:177
 XrdFileCloseReporter.cxx:178
 XrdFileCloseReporter.cxx:179
 XrdFileCloseReporter.cxx:180
 XrdFileCloseReporter.cxx:181
 XrdFileCloseReporter.cxx:182
 XrdFileCloseReporter.cxx:183
 XrdFileCloseReporter.cxx:184
 XrdFileCloseReporter.cxx:185
 XrdFileCloseReporter.cxx:186
 XrdFileCloseReporter.cxx:187
 XrdFileCloseReporter.cxx:188
 XrdFileCloseReporter.cxx:189
 XrdFileCloseReporter.cxx:190
 XrdFileCloseReporter.cxx:191
 XrdFileCloseReporter.cxx:192
 XrdFileCloseReporter.cxx:193
 XrdFileCloseReporter.cxx:194
 XrdFileCloseReporter.cxx:195
 XrdFileCloseReporter.cxx:196
 XrdFileCloseReporter.cxx:197
 XrdFileCloseReporter.cxx:198
 XrdFileCloseReporter.cxx:199
 XrdFileCloseReporter.cxx:200
 XrdFileCloseReporter.cxx:201
 XrdFileCloseReporter.cxx:202
 XrdFileCloseReporter.cxx:203
 XrdFileCloseReporter.cxx:204
 XrdFileCloseReporter.cxx:205
 XrdFileCloseReporter.cxx:206
 XrdFileCloseReporter.cxx:207
 XrdFileCloseReporter.cxx:208
 XrdFileCloseReporter.cxx:209
 XrdFileCloseReporter.cxx:210
 XrdFileCloseReporter.cxx:211
 XrdFileCloseReporter.cxx:212
 XrdFileCloseReporter.cxx:213
 XrdFileCloseReporter.cxx:214
 XrdFileCloseReporter.cxx:215
 XrdFileCloseReporter.cxx:216
 XrdFileCloseReporter.cxx:217
 XrdFileCloseReporter.cxx:218
 XrdFileCloseReporter.cxx:219
 XrdFileCloseReporter.cxx:220
 XrdFileCloseReporter.cxx:221
 XrdFileCloseReporter.cxx:222
 XrdFileCloseReporter.cxx:223
 XrdFileCloseReporter.cxx:224
 XrdFileCloseReporter.cxx:225