1// readerWriter.c
2
3#include "stdafx.h"
4
5#include "beCompat.h"
6#include "betalk.h"
7#include "readerWriter.h"
8
9
10bool initManagedData(bt_managed_data *data)
11{
12	data->readCount = 0;
13	data->writeCount = 0;
14
15	if (!(data->readCountSem = CreateSemaphore(NULL, 1, 1, NULL)))
16		return false;
17
18	if (!(data->writeCountSem = CreateSemaphore(NULL, 1, 1, NULL)))
19	{
20		CloseHandle(data->readCountSem);
21		return false;
22	}
23
24	if (!(data->readerQueue = CreateSemaphore(NULL, 1, 1, NULL)))
25	{
26		CloseHandle(data->writeCountSem);
27		CloseHandle(data->readCountSem);
28		return false;
29	}
30
31	if (!(data->reader = CreateSemaphore(NULL, 1, 1, NULL)))
32	{
33		CloseHandle(data->readerQueue);
34		CloseHandle(data->writeCountSem);
35		CloseHandle(data->readCountSem);
36		return false;
37	}
38
39	if (!(data->writer = CreateSemaphore(NULL, 1, 1, NULL)))
40	{
41		CloseHandle(data->reader);
42		CloseHandle(data->readerQueue);
43		CloseHandle(data->writeCountSem);
44		CloseHandle(data->readCountSem);
45		return false;
46	}
47
48	return true;
49}
50
51void closeManagedData(bt_managed_data *data)
52{
53	data->readCount = data->writeCount = 0;
54
55	CloseHandle(data->writer);
56	CloseHandle(data->reader);
57	CloseHandle(data->readerQueue);
58	CloseHandle(data->writeCountSem);
59	CloseHandle(data->readCountSem);
60}
61
62void beginReading(bt_managed_data *data)
63{
64	WaitForSingleObject(data->readerQueue, INFINITE);
65	WaitForSingleObject(data->reader, INFINITE);
66	WaitForSingleObject(data->readCountSem, INFINITE);
67
68	data->readCount++;
69	if (data->readCount == 1)
70		WaitForSingleObject(data->writer, INFINITE);
71
72	ReleaseSemaphore(data->readCountSem, 1, NULL);
73	ReleaseSemaphore(data->reader, 1, NULL);
74	ReleaseSemaphore(data->readerQueue, 1, NULL);
75}
76
77void endReading(bt_managed_data *data)
78{
79	WaitForSingleObject(data->readCountSem, INFINITE);
80
81	data->readCount--;
82	if (data->readCount == 0)
83		ReleaseSemaphore(data->writer, 1, NULL);
84
85	ReleaseSemaphore(data->readCountSem, 1, NULL);
86}
87
88void beginWriting(bt_managed_data *data)
89{
90	WaitForSingleObject(data->writeCountSem, INFINITE);
91
92	data->writeCount++;
93	if (data->writeCount == 1)
94		WaitForSingleObject(data->reader, INFINITE);
95
96	ReleaseSemaphore(data->writeCountSem, 1, NULL);
97	WaitForSingleObject(data->writer, INFINITE);
98}
99
100void endWriting(bt_managed_data *data)
101{
102	ReleaseSemaphore(data->writer, 1, NULL);
103	WaitForSingleObject(data->writeCountSem, INFINITE);
104
105	data->writeCount--;
106	if (data->writeCount == 0)
107		ReleaseSemaphore(data->reader, 1, NULL);
108
109	ReleaseSemaphore(data->writeCountSem, 1, NULL);
110}
111