summaryrefslogtreecommitdiffhomepage
path: root/faceapi/lockfree.h
blob: 47b810fabae6aaa6519c0cbaab7eb114383c59c6 (plain)
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
//lock free queue template class by Herb Sutter
//Dr Dobbs Journal article http://www.drdobbs.com/cpp/210604448;jsessionid=OQGQPSMNL4X4XQE1GHPSKH4ATMY32JVN?pgno=1

template <typename T> class LockFreeQueue
{
private:
	struct Node
	{
		Node( T val ) : value(val), next(nullptr) { }
		T value;
		Node* next;
	};
  
	Node* first;			// for producer only
	Node* divider, last;	// shared

	//not working in VC2008
	//atomic<Node*> divider, last;	// shared

public:
	LockFreeQueue()
	{
		// add dummy separator		
		first = divider = last = new Node( T() );
  	}

	~LockFreeQueue()
	{
		while( first != nullptr )
		{   
			// release the list			
			Node* tmp = first;
			first = tmp->next;
			delete tmp;
		}
	}

	void Produce( const T& t )
	{
		last->next = new Node(t);  	// add the new item
		last = last->next;			// publish it
    
		while( first != divider )
		{	
			// trim unused nodes			
			Node* tmp = first;
			first = first->next;
			delete tmp;
		}
	}

	bool Consume( T& result )
	{
		if( divider != last )
		{
			// if queue is nonempty			
			result = divider->next->value; 	// copy it back
			divider = divider->next; 		// publish that we took it
			return true;          			// and report success
    		}
		
		return false;           			// else report empty
	}
};