2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
5 * A class for running a series or set of processes, one at a time.
7 #ifndef __WVSUBPROCQUEUE_H
8 #define __WVSUBPROCQUEUE_H
10 #include "wvsubproc.h"
13 * An ordered queue of WvSubProc instances.
15 * You can enqueue any number of subprocesses to run sequentially, with
16 * a specified maximum number of processes running at a time. The processes
17 * run in the order they are added to the queue, except that (of course)
18 * running more than one process at a time may cause processes to overlap
19 * in an undefined way.
21 * You can define "sync point" subprocesses using the "cookie" parameter to
22 * add(). A sync point is guaranteed to be started:
23 * - alone, not in parallel with anything else
24 * - at least once after you enqueue it
25 * - at least once after every already-enqueued process has finished
26 * - immediately after every already-enqueued process has finished, *unless*
27 * an earlier sync point is still waiting.
28 * - no more than twice after the final time it is enqueued.
30 * That sounds complicated, but it lets you easily implement a common
31 * type of "delayed event" queuing: "Some time after each of these
32 * things S, I need to run X, but I don't need to run it for *every*
33 * element of S, but I don't want it to wait forever because I keep adding
36 * For example, imagine you have one type of operation, add() that
37 * creates a new file in a directory, and another type of operation
38 * that regenerates the directory index. You need to generate the
39 * index after any create operation before it will really be done,
40 * but there is no need to generate the index more than once when
41 * doing a lot of create operations. You could do a sequence like
44 * for (i = 0; i < 10; i++)
47 * Where "add" can trivially just do q.add(NULL, whatever1) and then
48 * q.add(&reindex_cookie, whatever2). WvSubProcQueue
49 * will ensure that "whatever2" runs as soon as possible (to prevent
50 * arbitrary delays because of nonstop add_file() calls) and also exactly
51 * once at the very end, but not every single time.
53 * In case it wasn't obvious, if you create more than one
54 * WvSubProcQueue, they operate totally independently of each other. That
55 * means if you have two queues with a max of 10 processes, you might have
56 * up to 20 processes running at a time.
62 * Create a WvSubProcQueue. _maxrunning is the maximum number of
63 * processes to have running in parallel. 1 is usually a good choice.
65 WvSubProcQueue(unsigned _maxrunning
);
67 virtual ~WvSubProcQueue();
70 * Enqueue a process. If cookie is NULL, the process will simply
71 * be added at the end of the queue. If cookie is non-NULL, it will
72 * be treated as a "sync point" as described above.
74 * WARNING! Do not start_again() the proc before passing it to the
75 * WvSubProcQueue. This is done automatically in some WvSubProc
76 * constructors. Use WvSubProc::prepare() or preparev() instead.
78 void add(void *cookie
, WvSubProc
*proc
);
81 * Like add(cookie, proc) but you don't have to build the WvSubProc
82 * yourself for simple cases.
84 void add(void *cookie
, const char *cmd
, const char * const *argv
);
87 * Clean up after any running processes in the queue, and start running
88 * additional processes if any are waiting. Never blocks.
90 * Returns the number of new processes which were started on this run.
92 * WARNING: you must call this rather often in order to keep your
98 * Wait synchronously for all processes in the entire queue to finish.
99 * This might block forever!! You should probably only call it in
100 * test programs or if you really know what you're doing. Otherwise
101 * just call go() occasionally.
105 /// Return the number of currently running processes.
106 unsigned running() const;
108 /// Return the number of unfinished (ie. running or waiting) processes.
109 unsigned remaining() const;
111 /// True if there are no unfinished (ie. running *or* waiting) processes.
112 bool isempty() const;
117 Ent(void *_cookie
, WvSubProc
*_proc
)
126 if (proc
) delete proc
;
138 bool cookie_running();
142 #endif // __WVSUBPROCQUEUE_H