31 callbackFunctionF: TIPCCallback; |
27 callbackFunctionF: TIPCCallback; |
32 callbackListenerThreadF: PSDL_Thread; |
28 callbackListenerThreadF: PSDL_Thread; |
33 callbackPointerN: pointer; |
29 callbackPointerN: pointer; |
34 callbackFunctionN: TIPCCallback; |
30 callbackFunctionN: TIPCCallback; |
35 callbackListenerThreadN: PSDL_Thread; |
31 callbackListenerThreadN: PSDL_Thread; |
36 |
32 queueFrontend, queueEngine, queueNet: PIPCQueue; |
37 procedure ipcSend(var s: TIPCMessage; var msg: TIPCMessage; mut: PSDL_mutex; cond: PSDL_cond); |
33 |
38 begin |
34 procedure ipcSend(var s: TIPCMessage; queue: PIPCQueue); |
39 SDL_LockMutex(mut); |
35 var pmsg: PIPCMessage; |
40 |
36 begin |
41 while (msg.str[0] > #0) or (msg.buf <> nil) do |
37 SDL_LockMutex(queue^.mut); |
42 SDL_CondWait(cond, mut); |
38 |
43 |
39 s.next:= nil; |
44 msg:= s; |
40 |
45 SDL_CondSignal(cond); |
41 if (queue^.msg.next = nil) and (queue^.msg.str[0] = #0) and (queue^.msg.buf = nil) then |
46 SDL_UnlockMutex(mut); |
|
47 end; |
|
48 |
|
49 function ipcRead(var msg: TIPCMessage; mut: PSDL_mutex; cond: PSDL_cond): TIPCMessage; |
|
50 var tmp: pointer; |
|
51 begin |
|
52 SDL_LockMutex(mut); |
|
53 while (msg.str[0] = #0) and (msg.buf = nil) do |
|
54 SDL_CondWait(cond, mut); |
|
55 |
|
56 if msg.buf <> nil then |
|
57 // FIXME is this copying really needed, the buffer is in another thread already anyway? |
|
58 begin |
42 begin |
59 tmp:= msg.buf; |
43 queue^.msg:= s; |
60 msg.buf:= GetMem(msg.len); |
44 end else |
61 Move(tmp^, msg.buf^, msg.len); |
45 begin |
62 FreeMem(tmp, msg.len) |
46 new(pmsg); |
|
47 pmsg^:= s; |
|
48 queue^.last^.next:= pmsg; |
|
49 queue^.last:= pmsg; |
63 end; |
50 end; |
64 |
51 SDL_CondSignal(queue^.cond); |
65 ipcRead:= msg; |
52 SDL_UnlockMutex(queue^.mut); |
66 |
53 end; |
67 msg.str[0]:= #0; |
54 |
68 msg.buf:= nil; |
55 function ipcRead(queue: PIPCQueue): TIPCMessage; |
69 |
56 var pmsg: PIPCMessage; |
70 SDL_CondSignal(cond); |
57 begin |
71 SDL_UnlockMutex(mut) |
58 SDL_LockMutex(queue^.mut); |
72 end; |
59 while (queue^.msg.str[0] = #0) and (queue^.msg.buf = nil) and (queue^.msg.next = nil) do |
73 |
60 SDL_CondWait(queue^.cond, queue^.mut); |
74 function ipcCheck(var msg: TIPCMessage; mut: PSDL_mutex): boolean; |
61 |
75 begin |
62 if (queue^.msg.str[0] <> #0) or (queue^.msg.buf <> nil) then |
76 SDL_LockMutex(mut); |
63 begin |
77 ipcCheck:= (msg.str[0] > #0) or (msg.buf <> nil); |
64 ipcRead:= queue^.msg; |
78 SDL_UnlockMutex(mut) |
65 queue^.msg.str[0]:= #0; |
|
66 queue^.msg.buf:= nil; |
|
67 end else |
|
68 begin |
|
69 pmsg:= queue^.msg.next; |
|
70 ipcRead:= pmsg^; |
|
71 queue^.msg.next:= pmsg^.next; |
|
72 if queue^.msg.next = nil then queue^.last:= @queue^.msg; |
|
73 dispose(pmsg) |
|
74 end; |
|
75 |
|
76 SDL_UnlockMutex(queue^.mut) |
|
77 end; |
|
78 |
|
79 function ipcCheck(queue: PIPCQueue): boolean; |
|
80 begin |
|
81 SDL_LockMutex(queue^.mut); |
|
82 ipcCheck:= (queue^.msg.str[0] > #0) or (queue^.msg.buf <> nil) or (queue^.msg.next <> nil); |
|
83 SDL_UnlockMutex(queue^.mut) |
79 end; |
84 end; |
80 |
85 |
81 procedure ipcToEngine(s: shortstring); |
86 procedure ipcToEngine(s: shortstring); |
82 var msg: TIPCMessage; |
87 var msg: TIPCMessage; |
83 begin |
88 begin |
84 msg.str:= s; |
89 msg.str:= s; |
85 msg.buf:= nil; |
90 msg.buf:= nil; |
86 ipcSend(msg, msgEngine, mutEngine, condEngine) |
91 ipcSend(msg, queueEngine) |
87 end; |
92 end; |
88 |
93 |
89 procedure ipcToFrontend(s: shortstring); |
94 procedure ipcToFrontend(s: shortstring); |
90 var msg: TIPCMessage; |
95 var msg: TIPCMessage; |
91 begin |
96 begin |
92 msg.str:= s; |
97 msg.str:= s; |
93 msg.buf:= nil; |
98 msg.buf:= nil; |
94 ipcSend(msg, msgFrontend, mutFrontend, condFrontend) |
99 ipcSend(msg, queueFrontend) |
95 end; |
100 end; |
96 |
101 |
97 procedure ipcToNet(s: shortstring); |
102 procedure ipcToNet(s: shortstring); |
98 var msg: TIPCMessage; |
103 var msg: TIPCMessage; |
99 begin |
104 begin |
100 msg.str:= s; |
105 msg.str:= s; |
101 msg.buf:= nil; |
106 msg.buf:= nil; |
102 ipcSend(msg, msgNet, mutNet, condNet) |
107 ipcSend(msg, queueNet) |
103 end; |
108 end; |
104 |
109 |
105 procedure ipcToEngineRaw(p: pointer; len: Longword); |
110 procedure ipcToEngineRaw(p: pointer; len: Longword); |
106 var msg: TIPCMessage; |
111 var msg: TIPCMessage; |
107 begin |
112 begin |
108 msg.str[0]:= #0; |
113 msg.str[0]:= #0; |
109 msg.len:= len; |
114 msg.len:= len; |
110 msg.buf:= GetMem(len); |
115 msg.buf:= GetMem(len); |
111 Move(p^, msg.buf^, len); |
116 Move(p^, msg.buf^, len); |
112 ipcSend(msg, msgEngine, mutEngine, condEngine) |
117 ipcSend(msg, queueEngine) |
113 end; |
118 end; |
114 |
119 |
115 procedure ipcToFrontendRaw(p: pointer; len: Longword); |
120 procedure ipcToFrontendRaw(p: pointer; len: Longword); |
116 var msg: TIPCMessage; |
121 var msg: TIPCMessage; |
117 begin |
122 begin |
118 msg.str[0]:= #0; |
123 msg.str[0]:= #0; |
119 msg.len:= len; |
124 msg.len:= len; |
120 msg.buf:= GetMem(len); |
125 msg.buf:= GetMem(len); |
121 Move(p^, msg.buf^, len); |
126 Move(p^, msg.buf^, len); |
122 ipcSend(msg, msgFrontend, mutFrontend, condFrontend) |
127 ipcSend(msg, queueFrontend) |
123 end; |
128 end; |
124 |
129 |
125 procedure ipcToNetRaw(p: pointer; len: Longword); |
130 procedure ipcToNetRaw(p: pointer; len: Longword); |
126 var msg: TIPCMessage; |
131 var msg: TIPCMessage; |
127 begin |
132 begin |
128 msg.str[0]:= #0; |
133 msg.str[0]:= #0; |
129 msg.len:= len; |
134 msg.len:= len; |
130 msg.buf:= GetMem(len); |
135 msg.buf:= GetMem(len); |
131 Move(p^, msg.buf^, len); |
136 Move(p^, msg.buf^, len); |
132 ipcSend(msg, msgNet, mutNet, condNet) |
137 ipcSend(msg, queueNet) |
133 end; |
138 end; |
134 |
139 |
135 function ipcReadFromEngine: TIPCMessage; |
140 function ipcReadFromEngine: TIPCMessage; |
136 begin |
141 begin |
137 ipcReadFromEngine:= ipcRead(msgFrontend, mutFrontend, condFrontend) |
142 ipcReadFromEngine:= ipcRead(queueFrontend) |
138 end; |
143 end; |
139 |
144 |
140 function ipcReadFromFrontend: shortstring; |
145 function ipcReadFromFrontend: shortstring; |
141 begin |
146 begin |
142 ipcReadFromFrontend:= ipcRead(msgEngine, mutEngine, condEngine).str |
147 ipcReadFromFrontend:= ipcRead(queueEngine).str |
143 end; |
148 end; |
144 |
149 |
145 function ipcReadToNet: TIPCMessage; |
150 function ipcReadToNet: TIPCMessage; |
146 begin |
151 begin |
147 ipcReadToNet:= ipcRead(msgNet, mutNet, condNet) |
152 ipcReadToNet:= ipcRead(queueNet) |
148 end; |
153 end; |
149 |
154 |
150 function ipcCheckFromEngine: boolean; |
155 function ipcCheckFromEngine: boolean; |
151 begin |
156 begin |
152 ipcCheckFromEngine:= ipcCheck(msgFrontend, mutFrontend) |
157 ipcCheckFromEngine:= ipcCheck(queueFrontend) |
153 end; |
158 end; |
154 |
159 |
155 function ipcCheckFromFrontend: boolean; |
160 function ipcCheckFromFrontend: boolean; |
156 begin |
161 begin |
157 ipcCheckFromFrontend:= ipcCheck(msgEngine, mutEngine) |
162 ipcCheckFromFrontend:= ipcCheck(queueEngine) |
158 end; |
163 end; |
159 |
164 |
160 function engineListener(p: pointer): Longint; cdecl; export; |
165 function engineListener(p: pointer): Longint; cdecl; export; |
161 var msg: TIPCMessage; |
166 var msg: TIPCMessage; |
162 begin |
167 begin |
201 callbackPointerN:= p; |
206 callbackPointerN:= p; |
202 callbackFunctionN:= f; |
207 callbackFunctionN:= f; |
203 callbackListenerThreadN:= SDL_CreateThread(@netListener, 'netListener', nil); |
208 callbackListenerThreadN:= SDL_CreateThread(@netListener, 'netListener', nil); |
204 end; |
209 end; |
205 |
210 |
|
211 function createQueue: PIPCQueue; |
|
212 var q: PIPCQueue; |
|
213 begin |
|
214 new(q); |
|
215 q^.msg.str:= ''; |
|
216 q^.msg.buf:= nil; |
|
217 q^.mut:= SDL_CreateMutex; |
|
218 q^.cond:= SDL_CreateCond; |
|
219 q^.msg.next:= nil; |
|
220 q^.last:= @q^.msg; |
|
221 createQueue:= q |
|
222 end; |
|
223 |
|
224 procedure destroyQueue(queue: PIPCQueue); |
|
225 begin |
|
226 SDL_DestroyCond(queue^.cond); |
|
227 SDL_DestroyMutex(queue^.mut); |
|
228 dispose(queue); |
|
229 end; |
|
230 |
206 procedure initIPC; |
231 procedure initIPC; |
207 begin |
232 begin |
208 msgFrontend.str:= ''; |
233 queueFrontend:= createQueue; |
209 msgFrontend.buf:= nil; |
234 queueEngine:= createQueue; |
210 msgEngine.str:= ''; |
235 queueNet:= createQueue; |
211 msgEngine.buf:= nil; |
|
212 msgNet.str:= ''; |
|
213 msgNet.buf:= nil; |
|
214 |
236 |
215 callbackPointerF:= nil; |
237 callbackPointerF:= nil; |
216 callbackListenerThreadF:= nil; |
238 callbackListenerThreadF:= nil; |
217 |
|
218 mutFrontend:= SDL_CreateMutex; |
|
219 mutEngine:= SDL_CreateMutex; |
|
220 mutNet:= SDL_CreateMutex; |
|
221 condFrontend:= SDL_CreateCond; |
|
222 condEngine:= SDL_CreateCond; |
|
223 condNet:= SDL_CreateCond; |
|
224 end; |
239 end; |
225 |
240 |
226 procedure freeIPC; |
241 procedure freeIPC; |
227 begin |
242 begin |
228 //FIXME SDL_KillThread(callbackListenerThreadF); |
243 //FIXME SDL_KillThread(callbackListenerThreadF); |
229 //FIXME SDL_KillThread(callbackListenerThreadN); |
244 //FIXME SDL_KillThread(callbackListenerThreadN); |
230 SDL_DestroyMutex(mutFrontend); |
245 destroyQueue(queueFrontend); |
231 SDL_DestroyMutex(mutEngine); |
246 destroyQueue(queueEngine); |
232 SDL_DestroyMutex(mutNet); |
247 destroyQueue(queueNet); |
233 SDL_DestroyCond(condFrontend); |
|
234 SDL_DestroyCond(condEngine); |
|
235 SDL_DestroyCond(condNet); |
|
236 end; |
248 end; |
237 |
249 |
238 end. |
250 end. |