dsrc isn't necessary for this repo
[client-tools.git] / src / external / 3rd / library / perforce / include / threading.h
blobfbbb89d3e579e1c5723891b76991677831d6462f
1 /*
2 * Copyright 1995, 2000 Perforce Software. All rights reserved.
4 * This file is part of Perforce - the FAST SCM System.
5 */
7 /*
8 * threading.h -- handle multiple users at the same time
10 * These classes are meant to take the vicious ifdef hacking required
11 * to get threading (forking, whatever) to work on different platforms.
13 * Some terms:
15 * "thread": a process on UNIX; a thread on NT
16 * "leader": the parent process on UNIX; the only process on NT
18 * Classes defined:
20 * Threading: caller interface to launch multiple threads
22 * Threader: implementation of threading (not public)
24 * Thread (abstract): glues caller's execution object so that Threading
25 * can run and then delete it.
27 * Process (abstract): callbacks into caller's environment to signal
28 * process related changes.
30 * Public methods:
32 * Thread::Run() - do what was supposed to happen in the thread
33 * Thread::~Thread() - delete user's class, cleaning up thread exit
35 * Process::Child() - indicates that Run() will be a child process
36 * Process::Cancel() - indicates that leader should stop launching
38 * Threading::Launch() - create a thread/process and call Thread::Run().
40 * Threading::Cancelled() - returns true (in leader) if Cancel()
42 * Threading::Cancel() - can be called from any thread to tell the
43 * leader to stop; leader calls Process::Cancel()
45 * Threading::Reap() - called in leader to kill children
47 * The current termination ritual:
49 * Someone, somewhere calls Threading::Cancel(), which is static
50 * and always available. It can get called by the leader
51 * catching SIGTERM, or by anyone at the user's request.
53 * If a child gets Threading::Cancel() on UNIX, it sends a SIGTERM
54 * to its parent so that the leader gets Threading::Cancel() called.
56 * In the leader, Threading::Cancel() sets the "cancelled" flag and
57 * calls Process::Cancel(), so that (in fact) the listen socket
58 * descriptor gets closed, breaking the accept() loop.
60 * The leader, out of its thread creation loop, can call Reap()
61 * in order to kill and collect all the child processes. It should
62 * only do that if the database is safely locked from child process
63 * access.
66 enum ThreadMode {
67 TmbSingle, // just single threading
68 TmbMulti, // multi threading (fork, threads)
69 TmbDaemon // fork, then forking multi threading (UNIX)
70 } ;
72 class Thread {
74 public:
76 virtual ~Thread();
77 virtual void Run() = 0;
79 } ;
81 class Process {
83 public:
85 virtual ~Process();
86 virtual void Child() = 0;
87 virtual void Cancel() = 0;
89 } ;
91 class Threader {
93 protected:
95 friend class Threading;
97 Threader() { cancelled = 0; }
99 virtual ~Threader();
100 virtual void Launch( Thread *t );
101 virtual void Cancel();
102 virtual void Reap();
104 int cancelled;
105 Process *process;
109 class Threading {
111 public:
112 Threading( ThreadMode tmb, Process *p );
113 ~Threading() { delete threader; }
115 void Launch( Thread *t ) { threader->Launch( t ); }
116 int Cancelled() { return threader->cancelled; }
117 void Reap() { threader->Reap(); }
119 static void Cancel() { if( current ) current->Cancel(); }
120 static int WasCancelled() { if( current ) return current->cancelled; else return 0; }
122 private:
124 Threader *threader;
126 static Threader *current;