From 13fc91124c4b59f366c7983aba78e0741f664da8 Mon Sep 17 00:00:00 2001 From: Dwight Date: Mon, 17 May 2010 18:06:53 -0400 Subject: [PATCH] task --- db/db.cpp | 1 + util/concurrency/task.cpp | 72 ++++++++++++++++++++++++++++++++++++--- util/concurrency/task.h | 26 ++++++++++---- 3 files changed, 88 insertions(+), 11 deletions(-) diff --git a/db/db.cpp b/db/db.cpp index 5f77a3c1db4..8b2238e7270 100644 --- a/db/db.cpp +++ b/db/db.cpp @@ -43,6 +43,7 @@ #include "module.h" #include "cmdline.h" #include "stats/snapshots.h" +#include "../util/concurrency/task.h" namespace mongo { diff --git a/util/concurrency/task.cpp b/util/concurrency/task.cpp index bd549eab29d..3347043d024 100644 --- a/util/concurrency/task.cpp +++ b/util/concurrency/task.cpp @@ -18,17 +18,79 @@ #include "pch.h" #include "task.h" +//#include "../goodies.h" namespace mongo { namespace task { - - Task::~Task() { } - void Task::run() { } +/* +#define MS_VC_EXCEPTION 0x406D1388 + +#pragma pack(push,8) +typedef struct tagTHREADNAME_INFO +{ + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. +} THREADNAME_INFO; +#pragma pack(pop) + +void SetThreadName( DWORD dwThreadID, char* threadName) +{ + Sleep(10); + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = threadName; + info.dwThreadID = dwThreadID; + info.dwFlags = 0; + + __try + { + RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info ); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + } +} +*/ - void fork(const shared_ptr& t) { - cout << "not yet implemented" << endl; + Task::Task() { + n = 0; + repeat = 0; + } + + void Task::halt() { repeat = 0; } + + void Task::run() { + //SetThreadName(-1, "A Task"); + assert( n == 0 ); + while( 1 ) { + n++; + try { + doWork(); + } + catch(...) { } + if( repeat == 0 ) + break; + sleepmillis(repeat); + } + me.reset(); + } + + void Task::begin(shared_ptr t) { + me = t; + go(); + } + + void fork(shared_ptr t) { + t->begin(t); + } + + void repeat(shared_ptr t, unsigned millis) { + t->repeat = millis; + t->begin(t); } } diff --git a/util/concurrency/task.h b/util/concurrency/task.h index 02a7968d727..c91df65277e 100644 --- a/util/concurrency/task.h +++ b/util/concurrency/task.h @@ -24,22 +24,36 @@ namespace mongo { namespace task { - class Task : protected BackgroundJob { - virtual void run(); + class Task : private BackgroundJob { protected: - virtual void go() = 0; + virtual void doWork() = 0; public: - virtual ~Task(); + Task(); + + /** for a repeating task, stop after current invocation ends. */ + void halt(); + + private: + shared_ptr me; + unsigned n, repeat; + friend void fork(shared_ptr t); + friend void repeat(shared_ptr t, unsigned millis); + virtual void run(); + void begin(shared_ptr); }; - void fork(const shared_ptr& t); + /* run once */ + void fork(shared_ptr t); + + /* run doWork() over and over, with a pause between runs of millis */ + void repeat(shared_ptr t, unsigned millis); /*** Example *** inline void sample() { class Sample : public Task { public: int result; - virtual void go() { result = 1234; } + virtual void doWork() { result = 1234; } Sample() : result(0) { } }; shared_ptr q( new Sample() );