-
Notifications
You must be signed in to change notification settings - Fork 0
/
Queue.c
153 lines (144 loc) · 2.93 KB
/
Queue.c
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include "Z-OS.h"
static void QueueInterfaceCreate(InternalObject* obj)
{
QueueInternal* intObj = zmalloc(sizeof(QueueInternal));
if (intObj)
{
obj->Data = intObj;
}
}
static void QueueInterfaceDestroy(InternalObject* obj)
{
zfree(obj->Data);
}
static Int16 QueueInterfaceAddItem(UInt16 handle, void* item)
{
InternalObject* obj;
Int16 ret;
if ((ret = InternalObjectFromHandle(handle,&obj))) return ret;
if (obj && obj->Data)
{
EnterCriticalSection();
AddListItem(&(((QueueInternal*)(obj->Data))->Items), item);
FinishWait(obj->Data, NULL);
ExitCriticalSection();
return ErrorSuccess;
}
else
{
return ErrorInvalidHandle;
}
}
static Int16 QueueInterfacePeek(UInt16 handle, void** item)
{
InternalObject* obj;
Int16 ret;
if ((ret = InternalObjectFromHandle(handle,&obj))) return ret;
if (obj && obj->Data)
{
EnterCriticalSection();
if (((QueueInternal*)(obj->Data))->Items.Length == 0)
{
*item = 0;
ExitCriticalSection();
return ErrorEmpty;
}
*item = GetListItem(&(((QueueInternal*)(obj->Data))->Items),0);
ExitCriticalSection();
return ErrorSuccess;
}
else
{
return ErrorInvalidHandle;
}
}
static Int16 QueueInterfaceGetItem(UInt16 handle, void** item)
{
InternalObject* obj;
Int16 ret;
if ((ret = InternalObjectFromHandle(handle,&obj))) return ret;
if (obj && obj->Data)
{
EnterCriticalSection();
if (((QueueInternal*)(obj->Data))->Items.Length == 0)
{
*item = 0;
ExitCriticalSection();
return ErrorEmpty;
}
*item = RemoveListItem(&(((QueueInternal*)(obj->Data))->Items),0);
ExitCriticalSection();
return ErrorSuccess;
}
else
{
return ErrorInvalidHandle;
}
}
static Int16 QueueInterfaceStartWait(UInt16 handle)
{
InternalObject* obj;
Int16 ret;
if ((ret = InternalObjectFromHandle(handle,&obj))) return ret;
if (obj && obj->Data)
{
EnterCriticalSection();
if (((QueueInternal*)(obj->Data))->Items.Length > 0)
{
ExitCriticalSection();
return ErrorNoWait;
}
ExitCriticalSection();
return ErrorSuccess;
}
else
{
return ErrorInvalidHandle;
}
}
static Int16 QueueGetInterface(Int16 code, void** interface)
{
switch (code)
{
case CodeIGeneric:
{
static const IGeneric inter =
{
QueueInterfaceCreate,
QueueInterfaceDestroy
};
*interface = (void*)&inter;
break;
}
case CodeIQueue:
{
static const IQueue inter =
{
QueueInterfaceAddItem,
QueueInterfacePeek,
QueueInterfaceGetItem
};
*interface = (void*)&inter;
break;
}
case CodeIWaitable:
{
static const IWaitable inter =
{
QueueInterfaceStartWait
};
*interface = (void*)&inter;
break;
}
default:
return ErrorInvalidInterface;
}
return ErrorSuccess;
}
void InitializeQueues(void)
{
TypeRegistration type;
type.Type = TypeQueue;
type.GetInterface = (void*)QueueGetInterface;
RegisterTypeManager(type);
}