File: ThreadGroup.h

package info (click to toggle)
storm-lang 0.7.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 52,028 kB
  • sloc: ansic: 261,471; cpp: 140,432; sh: 14,891; perl: 9,846; python: 2,525; lisp: 2,504; asm: 860; makefile: 678; pascal: 70; java: 52; xml: 37; awk: 12
file content (108 lines) | stat: -rw-r--r-- 2,739 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#pragma once
#include "Thread.h"
#include "Sync.h"
#include "Utils/Lock.h"
#include "Utils/Function.h"

namespace os {

	class ThreadGroupData;

	/**
	 * Thread group. A thread group allows the owner of the thread group to wait until all members
	 * of that group have terminated. Beware to not add threads when calling join(), since there
	 * will be a race condition between the newly created thread and the terminating threads, which
	 * means that the thread group may not be empty after a 'join'.
	 */
	class ThreadGroup {
		friend class Thread;
	public:
		// Create.
		ThreadGroup();

		// Callbacks called on thread start or thread termination.
		typedef util::Fn<void> Callback;
		ThreadGroup(Callback start, Callback stop);

		// Copy.
		ThreadGroup(const ThreadGroup &o);

		// Destroy.
		~ThreadGroup();

		// Assign.
		ThreadGroup &operator =(const ThreadGroup &o);

		// Get a list of all threads currently in the group.
		vector<Thread> threads() const;

		// Wait for all threads in this group to exit. Only call from one thread!
		void join();

	private:
		// Data object we're referring.
		ThreadGroupData *data;
	};


	/**
	 * Shared data for thread group objects.
	 */
	class ThreadGroupData : NoCopy {
	public:
		// Create, initialize to one reference.
		ThreadGroupData();
		ThreadGroupData(ThreadGroup::Callback start, ThreadGroup::Callback stop);
		~ThreadGroupData();

		// Add reference.
		inline void addRef() {
			atomicIncrement(references);
		}

		// Release.
		inline void release() {
			if (atomicDecrement(references) == 0)
				delete this;
		}

		// Notify a new thread has started.
		void threadStarted(ThreadData *data);

		// Notify that a thread is about to terminate. This is called when the thread believes that
		// it is no longer reachable. This is not a final decision as we may hand out references to
		// it. If 'false' is returned, there is a reference to the thread again, and termination
		// shall be held off for a while.
		bool threadUnreachable(ThreadData *data);

		// Notify a thread is terminated. This is a final decision, and should be called after 'threadUnreachable'.
		void threadTerminated();

		// Get all threads in this group.
		vector<Thread> threads();

		// Wait for all threads to terminate.
		void join();

	private:
		// Number of references.
		nat references;

		// Total number of threads attached.
		nat attached;

		// All threads currently running. Used to be able to produce a list of threads in the thread group.
		InlineSet<ThreadData> running;

		// Lock for the thread set.
		util::Lock runningLock;

		// Semaphore for waiting.
		Sema sema;

		// Callbacks for thread creation/termination.
		ThreadGroup::Callback start;
		ThreadGroup::Callback stop;
	};

}