/* * Copyright 1995, 2000 Perforce Software. All rights reserved. * * This file is part of Perforce - the FAST SCM System. */ /* * threading.h -- handle multiple users at the same time * * These classes are meant to take the vicious ifdef hacking required * to get threading (forking, whatever) to work on different platforms. * * Some terms: * * "thread": a process on UNIX; a thread on NT * "leader": the parent process on UNIX; the only process on NT * * Classes defined: * * Threading: caller interface to launch multiple threads * * Threader: implementation of threading (not public) * * Thread (abstract): glues caller's execution object so that Threading * can run and then delete it. * * Process (abstract): callbacks into caller's environment to signal * process related changes. * * Public methods: * * Thread::Run() - do what was supposed to happen in the thread * Thread::~Thread() - delete user's class, cleaning up thread exit * * Process::Child() - indicates that Run() will be a child process * Process::Cancel() - indicates that leader should stop launching * * Threading::Launch() - create a thread/process and call Thread::Run(). * * Threading::Cancelled() - returns true (in leader) if Cancel() * Threading::Restarted() - returns true (in leader) if Restart() * * Threading::Cancel() - can be called from any thread to tell the * leader to stop; leader calls Process::Cancel() * Threading::Restart() - can be called from any thread to tell the * leader to restart; leader calls Process::Restart() * * Threading::Reap() - called in leader to kill children * * Threading::GetThreadCount() - returns the current number of threads * Only valid in the parent/main process! * * The current termination ritual: * * Someone, somewhere calls Threading::Cancel(), which is static * and always available. It can get called by the leader * catching SIGTERM, or by anyone at the user's request. * * If a child gets Threading::Cancel() on UNIX, it sends a SIGTERM * to its parent so that the leader gets Threading::Cancel() called. * * In the leader, Threading::Cancel() sets the "cancelled" flag and * calls Process::Cancel(), so that (in fact) the listen socket * descriptor gets closed, breaking the accept() loop. * * The leader, out of its thread creation loop, can call Reap() * in order to kill and collect all the child processes. It should * only do that if the database is safely locked from child process * access. * * Restart is just like Cancel but the leader re-starts all processing rather * than exiting. */ enum ThreadMode { TmbSingle, // just single threading TmbMulti, // multi threading (fork, threads) TmbDaemon // fork, then forking multi threading (UNIX) } ; class Thread { public: virtual ~Thread(); virtual void Run() = 0; } ; class Process { public: virtual ~Process(); virtual void Child() = 0; virtual void Cancel() = 0; } ; class Threader { protected: friend class Threading; Threader() { cancelled = 0; restarted = 0; threadCount = 0; process = 0; } virtual ~Threader(); virtual void Launch( Thread *t ); virtual void Cancel(); virtual void Restart(); virtual void Quiesce(); virtual void Reap(); virtual int GetThreadCount(); // varies on each system int cancelled; int restarted; Process *process; int threadCount; // not used by all implementations... } ; class Threading { public: Threading( ThreadMode tmb, Process *p ); ~Threading() { delete threader; } void Launch( Thread *t ) { threader->Launch( t ); } int Cancelled() { return threader->cancelled; } int Restarted() { return threader->restarted; } void Quiesce() { threader->Quiesce(); } void Reap() { threader->Reap(); } static void Cancel() { if( current ) current->Cancel(); } static void Restart() { if( current ) current->Restart(); } static int WasCancelled() { if( current ) return current->cancelled; else return 0; } static int WasRestarted() { if( current ) return current->restarted; else return 0; } static int GetThreadCount() { return current ? current->GetThreadCount() : -1; } static void LaunchCurrentThread( Thread *t ) { if( current ) current->Launch( t ); } private: Threader *threader; static Threader *current; } ;
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 16129 | tjuricek |
Rename/move files again... this time to the hyphenated-approach. |
||
//guest/tjuricek/file_system_client/main/vendor/p4api-15.1/macosx105x86_64/include/p4/threading.h | |||||
#1 | 16119 | tjuricek | Rename/move to meet workshop project conventions. | ||
//guest/tjuricek/fsclient/vendor/p4api-15.1/macosx105x86_64/include/p4/threading.h | |||||
#1 | 16118 | tjuricek |
FSClient initial version: handles add, edit This is a proof-of-concept app that mirrors an existing Perforce workspace to handle running commands like "p4 add" and "p4 edit" automatically when your apps add and write files. See the readme for more information. |