/* * 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; } private: Threader *threader; static Threader *current; } ;
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 12290 | geekstress |
Branching //guest/perforce_software/p4connect/... to //guest/geekstress/dev/p4connect/... |
||
//guest/perforce_software/p4connect/src/P4Bridge/p4api/include/p4/threading.h | |||||
#2 | 12135 | Norman Morse |
Integrate dev branch changes into main. This code is the basiis of the 2.7 BETA release which provides Unity 5 compatibility |
||
#1 | 10940 | Norman Morse |
Inital Workshop release of P4Connect. Released under BSD-2 license |