/usr/include/mongo/util/background.h is in mongodb-dev 1:2.4.9-1ubuntu2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | // @file background.h
/* Copyright 2009 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <string>
#include <vector>
#include "concurrency/spin_lock.h"
namespace mongo {
/**
* Background thread dispatching.
* subclass and define run()
*
* It is ok to call go(), that is, run the job, more than once -- if the
* previous invocation has finished. Thus one pattern of use is to embed
* a backgroundjob in your object and reuse it (or same thing with
* inheritance). Each go() call spawns a new thread.
*
* Thread safety:
* note when job destructs, the thread is not terminated if still running.
* generally if the thread could still be running, allocate the job dynamically
* and set deleteSelf to true.
*
* go() and wait() are not thread safe
* run() will be executed on the background thread
* BackgroundJob object must exist for as long the background thread is running
*/
class BackgroundJob : boost::noncopyable {
protected:
/**
* sub-class must instantiate the BackgroundJob
*
* @param selfDelete if set to true, object will destruct itself after the run() finished
* @note selfDelete instances cannot be wait()-ed upon
*/
explicit BackgroundJob(bool selfDelete = false);
virtual std::string name() const = 0;
/**
* define this to do your work.
* after this returns, state is set to done.
* after this returns, deleted if deleteSelf true.
*
* NOTE:
* if run() throws, the exception will be caught within 'this' object and will ultimately lead to the
* BackgroundJob's thread being finished, as if run() returned.
*
*/
virtual void run() = 0;
public:
enum State {
NotStarted,
Running,
Done
};
virtual ~BackgroundJob() { }
/**
* starts job.
* returns immediately after dispatching.
*
* @note the BackgroundJob object must live for as long the thread is still running, ie
* until getState() returns Done.
*/
BackgroundJob& go();
/**
* wait for completion.
*
* @param msTimeOut maximum amount of time to wait in milliseconds
* @return true if did not time out. false otherwise.
*
* @note you can call wait() more than once if the first call times out.
* but you cannot call wait on a self-deleting job.
*/
bool wait( unsigned msTimeOut = 0 );
// accessors
State getState() const;
bool running() const;
private:
struct JobStatus;
boost::shared_ptr<JobStatus> _status; // shared between 'this' and body() thread
void jobBody( boost::shared_ptr<JobStatus> status );
};
/**
* these run "roughly" every minute
* instantiate statically
* class MyTask : public PeriodicTask {
* public:
* virtual std::string name() const { return "MyTask; " }
* virtual void doWork() { log() << "hi" << endl; }
* } myTask;
*/
class PeriodicTask {
public:
PeriodicTask();
virtual ~PeriodicTask();
virtual void taskDoWork() = 0;
virtual std::string taskName() const = 0;
class Runner : public BackgroundJob {
public:
virtual ~Runner(){}
virtual std::string name() const { return "PeriodicTask::Runner"; }
virtual void run();
void add( PeriodicTask* task );
void remove( PeriodicTask* task );
private:
SpinLock _lock;
// these are NOT owned by Runner
// Runner will not delete these
// this never gets smaller
// only fields replaced with nulls
std::vector< PeriodicTask* > _tasks;
};
static Runner* theRunner;
};
} // namespace mongo
|