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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
// Event.cpp
// Implements the cEvent object representing an OS-specific synchronization primitive that can be waited-for
// Implemented as an Event on Win and as a 1-semaphore on *nix
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "Event.h"
#if not defined(_WIN32)
#include <string.h>
#endif
cEvent::cEvent(void)
{
#ifdef _WIN32
m_Event = CreateEvent(NULL, FALSE, FALSE, NULL);
if (m_Event == NULL)
{
LOGERROR("cEvent: cannot create event, GLE = %d. Aborting server.", GetLastError());
abort();
}
#else // *nix
m_bIsNamed = false;
m_Event = new sem_t;
if (sem_init(m_Event, 0, 0))
{
// This path is used by MacOS, because it doesn't support unnamed semaphores.
delete m_Event;
m_bIsNamed = true;
AString EventName;
Printf(EventName, "cEvent%p", this);
m_Event = sem_open(EventName.c_str(), O_CREAT, 777, 0 );
if (m_Event == SEM_FAILED)
{
char buffer[1024];
strerror_r(errno,buffer,1024);
LOGERROR("cEvent: Cannot create event, err = %s. Aborting server.", buffer);
abort();
}
// Unlink the semaphore immediately - it will continue to function but will not pollute the namespace
// We don't store the name, so can't call this in the destructor
if (sem_unlink(EventName.c_str()) != 0)
{
char buffer[1024];
strerror_r(errno,buffer,1024);
LOGWARN("ERROR: Could not unlink cEvent. (%s)", buffer);
}
}
#endif // *nix
}
cEvent::~cEvent()
{
#ifdef _WIN32
CloseHandle(m_Event);
#else
if (m_bIsNamed)
{
if (sem_close(m_Event) != 0)
{
char buffer[1024];
strerror_r(errno,buffer,1024);
LOGERROR("ERROR: Could not close cEvent. (%s)", buffer);
}
}
else
{
sem_destroy(m_Event);
delete m_Event;
}
#endif
}
void cEvent::Wait(void)
{
#ifdef _WIN32
DWORD res = WaitForSingleObject(m_Event, INFINITE);
if (res != WAIT_OBJECT_0)
{
LOGWARN("cEvent: waiting for the event failed: %d, GLE = %d. Continuing, but server may be unstable.", res, GetLastError());
}
#else
int res = sem_wait(m_Event);
if (res != 0 )
{
char buffer[1024];
strerror_r(errno,buffer,1024);
LOGWARN("cEvent: waiting for the event failed: %i, err = %s. Continuing, but server may be unstable.", res, buffer);
}
#endif
}
void cEvent::Set(void)
{
#ifdef _WIN32
if (!SetEvent(m_Event))
{
LOGWARN("cEvent: Could not set cEvent: GLE = %d", GetLastError());
}
#else
int res = sem_post(m_Event);
if (res != 0)
{
char buffer[1024];
strerror_r(errno,buffer,1024);
LOGWARN("cEvent: Could not set cEvent: %i, err = %s", res, buffer);
}
#endif
}
|