File: | Xext/sync.c |
Location: | line 1285, column 27 |
Description: | Access to field 'counter' results in a dereference of a null pointer (loaded from variable 'walklist') |
1 | /* | |||
2 | ||||
3 | Copyright 1991, 1993, 1998 The Open Group | |||
4 | ||||
5 | Permission to use, copy, modify, distribute, and sell this software and its | |||
6 | documentation for any purpose is hereby granted without fee, provided that | |||
7 | the above copyright notice appear in all copies and that both that | |||
8 | copyright notice and this permission notice appear in supporting | |||
9 | documentation. | |||
10 | ||||
11 | The above copyright notice and this permission notice shall be included | |||
12 | in all copies or substantial portions of the Software. | |||
13 | ||||
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
15 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |||
17 | IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR | |||
18 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |||
19 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |||
20 | OTHER DEALINGS IN THE SOFTWARE. | |||
21 | ||||
22 | Except as contained in this notice, the name of The Open Group shall | |||
23 | not be used in advertising or otherwise to promote the sale, use or | |||
24 | other dealings in this Software without prior written authorization | |||
25 | from The Open Group. | |||
26 | ||||
27 | Copyright 1991, 1993 by Digital Equipment Corporation, Maynard, Massachusetts, | |||
28 | and Olivetti Research Limited, Cambridge, England. | |||
29 | ||||
30 | All Rights Reserved | |||
31 | ||||
32 | Permission to use, copy, modify, and distribute this software and its | |||
33 | documentation for any purpose and without fee is hereby granted, | |||
34 | provided that the above copyright notice appear in all copies and that | |||
35 | both that copyright notice and this permission notice appear in | |||
36 | supporting documentation, and that the names of Digital or Olivetti | |||
37 | not be used in advertising or publicity pertaining to distribution of the | |||
38 | software without specific, written prior permission. Digital and Olivetti | |||
39 | make no representations about the suitability of this software | |||
40 | for any purpose. It is provided "as is" without express or implied warranty. | |||
41 | ||||
42 | DIGITAL AND OLIVETTI DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | |||
43 | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||
44 | FITNESS, IN NO EVENT SHALL THEY BE LIABLE FOR ANY SPECIAL, INDIRECT OR | |||
45 | CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF | |||
46 | USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | |||
47 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |||
48 | PERFORMANCE OF THIS SOFTWARE. | |||
49 | ||||
50 | */ | |||
51 | ||||
52 | #ifdef HAVE_DIX_CONFIG_H1 | |||
53 | #include <dix-config.h> | |||
54 | #endif | |||
55 | ||||
56 | #include <string.h> | |||
57 | ||||
58 | #include <X11/X.h> | |||
59 | #include <X11/Xproto.h> | |||
60 | #include <X11/Xmd.h> | |||
61 | #include "scrnintstr.h" | |||
62 | #include "os.h" | |||
63 | #include "extnsionst.h" | |||
64 | #include "dixstruct.h" | |||
65 | #include "pixmapstr.h" | |||
66 | #include "resource.h" | |||
67 | #include "opaque.h" | |||
68 | #include <X11/extensions/syncproto.h> | |||
69 | #include "syncsrv.h" | |||
70 | #include "syncsdk.h" | |||
71 | #include "protocol-versions.h" | |||
72 | #include "inputstr.h" | |||
73 | ||||
74 | #include <stdio.h> | |||
75 | #if !defined(WIN32) | |||
76 | #include <sys/time.h> | |||
77 | #endif | |||
78 | ||||
79 | #include "extinit.h" | |||
80 | ||||
81 | /* | |||
82 | * Local Global Variables | |||
83 | */ | |||
84 | static int SyncEventBase; | |||
85 | static int SyncErrorBase; | |||
86 | static RESTYPE RTCounter = 0; | |||
87 | static RESTYPE RTAwait; | |||
88 | static RESTYPE RTAlarm; | |||
89 | static RESTYPE RTAlarmClient; | |||
90 | static RESTYPE RTFence; | |||
91 | static struct xorg_list SysCounterList; | |||
92 | static int SyncNumInvalidCounterWarnings = 0; | |||
93 | ||||
94 | #define MAX_INVALID_COUNTER_WARNINGS5 5 | |||
95 | ||||
96 | static const char *WARN_INVALID_COUNTER_COMPARE = | |||
97 | "Warning: Non-counter XSync object using Counter-only\n" | |||
98 | " comparison. Result will never be true.\n"; | |||
99 | ||||
100 | static const char *WARN_INVALID_COUNTER_ALARM = | |||
101 | "Warning: Non-counter XSync object used in alarm. This is\n" | |||
102 | " the result of a programming error in the X server.\n"; | |||
103 | ||||
104 | #define IsSystemCounter(pCounter)(pCounter && (pCounter->sync.client == ((void*)0)) ) \ | |||
105 | (pCounter && (pCounter->sync.client == NULL((void*)0))) | |||
106 | ||||
107 | /* these are all the alarm attributes that pertain to the alarm's trigger */ | |||
108 | #define XSyncCAAllTrigger((1L<<0) | (1L<<1) | (1L<<2) | (1L<<3 )) \ | |||
109 | (XSyncCACounter(1L<<0) | XSyncCAValueType(1L<<1) | XSyncCAValue(1L<<2) | XSyncCATestType(1L<<3)) | |||
110 | ||||
111 | static void SyncComputeBracketValues(SyncCounter *); | |||
112 | ||||
113 | static void SyncInitServerTime(void); | |||
114 | ||||
115 | static void SyncInitIdleTime(void); | |||
116 | ||||
117 | static inline void* | |||
118 | SysCounterGetPrivate(SyncCounter *counter) | |||
119 | { | |||
120 | BUG_WARN(!IsSystemCounter(counter))do { if (!(counter && (counter->sync.client == ((void *)0)))) { ErrorFSigSafe("BUG: triggered 'if (" "!(counter && (counter->sync.client == ((void*)0)))" ")'\n"); ErrorFSigSafe("BUG: %s:%u in %s()\n", "sync.c", 120 , __func__); if (0) ErrorFSigSafe(((void*)0)); xorg_backtrace (); } } while(0); | |||
121 | ||||
122 | return counter->pSysCounterInfo ? counter->pSysCounterInfo->private : NULL((void*)0); | |||
123 | } | |||
124 | ||||
125 | static Bool | |||
126 | SyncCheckWarnIsCounter(const SyncObject * pSync, const char *warning) | |||
127 | { | |||
128 | if (pSync && (SYNC_COUNTER0 != pSync->type)) { | |||
129 | if (SyncNumInvalidCounterWarnings++ < MAX_INVALID_COUNTER_WARNINGS5) { | |||
130 | ErrorF("%s", warning); | |||
131 | ErrorF(" Counter type: %d\n", pSync->type); | |||
132 | } | |||
133 | ||||
134 | return FALSE0; | |||
135 | } | |||
136 | ||||
137 | return TRUE1; | |||
138 | } | |||
139 | ||||
140 | /* Each counter maintains a simple linked list of triggers that are | |||
141 | * interested in the counter. The two functions below are used to | |||
142 | * delete and add triggers on this list. | |||
143 | */ | |||
144 | void | |||
145 | SyncDeleteTriggerFromSyncObject(SyncTrigger * pTrigger) | |||
146 | { | |||
147 | SyncTriggerList *pCur; | |||
148 | SyncTriggerList *pPrev; | |||
149 | SyncCounter *pCounter; | |||
150 | ||||
151 | /* pSync needs to be stored in pTrigger before calling here. */ | |||
152 | ||||
153 | if (!pTrigger->pSync) | |||
154 | return; | |||
155 | ||||
156 | pPrev = NULL((void*)0); | |||
157 | pCur = pTrigger->pSync->pTriglist; | |||
158 | ||||
159 | while (pCur) { | |||
160 | if (pCur->pTrigger == pTrigger) { | |||
161 | if (pPrev) | |||
162 | pPrev->next = pCur->next; | |||
163 | else | |||
164 | pTrigger->pSync->pTriglist = pCur->next; | |||
165 | ||||
166 | free(pCur); | |||
167 | break; | |||
168 | } | |||
169 | ||||
170 | pPrev = pCur; | |||
171 | pCur = pCur->next; | |||
172 | } | |||
173 | ||||
174 | if (SYNC_COUNTER0 == pTrigger->pSync->type) { | |||
175 | pCounter = (SyncCounter *) pTrigger->pSync; | |||
176 | ||||
177 | if (IsSystemCounter(pCounter)(pCounter && (pCounter->sync.client == ((void*)0)) )) | |||
178 | SyncComputeBracketValues(pCounter); | |||
179 | } | |||
180 | else if (SYNC_FENCE1 == pTrigger->pSync->type) { | |||
181 | SyncFence *pFence = (SyncFence *) pTrigger->pSync; | |||
182 | ||||
183 | pFence->funcs.DeleteTrigger(pTrigger); | |||
184 | } | |||
185 | } | |||
186 | ||||
187 | int | |||
188 | SyncAddTriggerToSyncObject(SyncTrigger * pTrigger) | |||
189 | { | |||
190 | SyncTriggerList *pCur; | |||
191 | SyncCounter *pCounter; | |||
192 | ||||
193 | if (!pTrigger->pSync) | |||
194 | return Success0; | |||
195 | ||||
196 | /* don't do anything if it's already there */ | |||
197 | for (pCur = pTrigger->pSync->pTriglist; pCur; pCur = pCur->next) { | |||
198 | if (pCur->pTrigger == pTrigger) | |||
199 | return Success0; | |||
200 | } | |||
201 | ||||
202 | if (!(pCur = malloc(sizeof(SyncTriggerList)))) | |||
203 | return BadAlloc11; | |||
204 | ||||
205 | pCur->pTrigger = pTrigger; | |||
206 | pCur->next = pTrigger->pSync->pTriglist; | |||
207 | pTrigger->pSync->pTriglist = pCur; | |||
208 | ||||
209 | if (SYNC_COUNTER0 == pTrigger->pSync->type) { | |||
210 | pCounter = (SyncCounter *) pTrigger->pSync; | |||
211 | ||||
212 | if (IsSystemCounter(pCounter)(pCounter && (pCounter->sync.client == ((void*)0)) )) | |||
213 | SyncComputeBracketValues(pCounter); | |||
214 | } | |||
215 | else if (SYNC_FENCE1 == pTrigger->pSync->type) { | |||
216 | SyncFence *pFence = (SyncFence *) pTrigger->pSync; | |||
217 | ||||
218 | pFence->funcs.AddTrigger(pTrigger); | |||
219 | } | |||
220 | ||||
221 | return Success0; | |||
222 | } | |||
223 | ||||
224 | /* Below are five possible functions that can be plugged into | |||
225 | * pTrigger->CheckTrigger for counter sync objects, corresponding to | |||
226 | * the four possible test-types, and the one possible function that | |||
227 | * can be plugged into pTrigger->CheckTrigger for fence sync objects. | |||
228 | * These functions are called after the sync object's state changes | |||
229 | * but are also passed the old state so they can inspect both the old | |||
230 | * and new values. (PositiveTransition and NegativeTransition need to | |||
231 | * see both pieces of information.) These functions return the truth | |||
232 | * value of the trigger. | |||
233 | * | |||
234 | * All of them include the condition pTrigger->pSync == NULL. | |||
235 | * This is because the spec says that a trigger with a sync value | |||
236 | * of None is always TRUE. | |||
237 | */ | |||
238 | ||||
239 | static Bool | |||
240 | SyncCheckTriggerPositiveComparison(SyncTrigger * pTrigger, CARD64XSyncValue oldval) | |||
241 | { | |||
242 | SyncCounter *pCounter; | |||
243 | ||||
244 | /* Non-counter sync objects should never get here because they | |||
245 | * never trigger this comparison. */ | |||
246 | if (!SyncCheckWarnIsCounter(pTrigger->pSync, WARN_INVALID_COUNTER_COMPARE)) | |||
247 | return FALSE0; | |||
248 | ||||
249 | pCounter = (SyncCounter *) pTrigger->pSync; | |||
250 | ||||
251 | return (pCounter == NULL((void*)0) || | |||
252 | XSyncValueGreaterOrEqual(pCounter->value, pTrigger->test_value)((pCounter->value).hi>(pTrigger->test_value).hi || ( (pCounter->value).hi==(pTrigger->test_value).hi && (pCounter->value).lo>=(pTrigger->test_value).lo))); | |||
253 | } | |||
254 | ||||
255 | static Bool | |||
256 | SyncCheckTriggerNegativeComparison(SyncTrigger * pTrigger, CARD64XSyncValue oldval) | |||
257 | { | |||
258 | SyncCounter *pCounter; | |||
259 | ||||
260 | /* Non-counter sync objects should never get here because they | |||
261 | * never trigger this comparison. */ | |||
262 | if (!SyncCheckWarnIsCounter(pTrigger->pSync, WARN_INVALID_COUNTER_COMPARE)) | |||
263 | return FALSE0; | |||
264 | ||||
265 | pCounter = (SyncCounter *) pTrigger->pSync; | |||
266 | ||||
267 | return (pCounter == NULL((void*)0) || | |||
268 | XSyncValueLessOrEqual(pCounter->value, pTrigger->test_value)((pCounter->value).hi<(pTrigger->test_value).hi || ( (pCounter->value).hi==(pTrigger->test_value).hi && (pCounter->value).lo<=(pTrigger->test_value).lo))); | |||
269 | } | |||
270 | ||||
271 | static Bool | |||
272 | SyncCheckTriggerPositiveTransition(SyncTrigger * pTrigger, CARD64XSyncValue oldval) | |||
273 | { | |||
274 | SyncCounter *pCounter; | |||
275 | ||||
276 | /* Non-counter sync objects should never get here because they | |||
277 | * never trigger this comparison. */ | |||
278 | if (!SyncCheckWarnIsCounter(pTrigger->pSync, WARN_INVALID_COUNTER_COMPARE)) | |||
279 | return FALSE0; | |||
280 | ||||
281 | pCounter = (SyncCounter *) pTrigger->pSync; | |||
282 | ||||
283 | return (pCounter == NULL((void*)0) || | |||
284 | (XSyncValueLessThan(oldval, pTrigger->test_value)((oldval).hi<(pTrigger->test_value).hi || ((oldval).hi== (pTrigger->test_value).hi && (oldval).lo<(pTrigger ->test_value).lo)) && | |||
285 | XSyncValueGreaterOrEqual(pCounter->value, pTrigger->test_value)((pCounter->value).hi>(pTrigger->test_value).hi || ( (pCounter->value).hi==(pTrigger->test_value).hi && (pCounter->value).lo>=(pTrigger->test_value).lo)))); | |||
286 | } | |||
287 | ||||
288 | static Bool | |||
289 | SyncCheckTriggerNegativeTransition(SyncTrigger * pTrigger, CARD64XSyncValue oldval) | |||
290 | { | |||
291 | SyncCounter *pCounter; | |||
292 | ||||
293 | /* Non-counter sync objects should never get here because they | |||
294 | * never trigger this comparison. */ | |||
295 | if (!SyncCheckWarnIsCounter(pTrigger->pSync, WARN_INVALID_COUNTER_COMPARE)) | |||
296 | return FALSE0; | |||
297 | ||||
298 | pCounter = (SyncCounter *) pTrigger->pSync; | |||
299 | ||||
300 | return (pCounter == NULL((void*)0) || | |||
301 | (XSyncValueGreaterThan(oldval, pTrigger->test_value)((oldval).hi>(pTrigger->test_value).hi || ((oldval).hi== (pTrigger->test_value).hi && (oldval).lo>(pTrigger ->test_value).lo)) && | |||
302 | XSyncValueLessOrEqual(pCounter->value, pTrigger->test_value)((pCounter->value).hi<(pTrigger->test_value).hi || ( (pCounter->value).hi==(pTrigger->test_value).hi && (pCounter->value).lo<=(pTrigger->test_value).lo)))); | |||
303 | } | |||
304 | ||||
305 | static Bool | |||
306 | SyncCheckTriggerFence(SyncTrigger * pTrigger, CARD64XSyncValue unused) | |||
307 | { | |||
308 | SyncFence *pFence = (SyncFence *) pTrigger->pSync; | |||
309 | ||||
310 | (void) unused; | |||
311 | ||||
312 | return (pFence == NULL((void*)0) || pFence->funcs.CheckTriggered(pFence)); | |||
313 | } | |||
314 | ||||
315 | static int | |||
316 | SyncInitTrigger(ClientPtr client, SyncTrigger * pTrigger, XID syncObject, | |||
317 | RESTYPE resType, Mask changes) | |||
318 | { | |||
319 | SyncObject *pSync = pTrigger->pSync; | |||
320 | SyncCounter *pCounter = NULL((void*)0); | |||
321 | int rc; | |||
322 | Bool newSyncObject = FALSE0; | |||
323 | ||||
324 | if (changes & XSyncCACounter(1L<<0)) { | |||
325 | if (syncObject == None0L) | |||
326 | pSync = NULL((void*)0); | |||
327 | else if (Success0 != (rc = dixLookupResourceByType((void **) &pSync, | |||
328 | syncObject, resType, | |||
329 | client, | |||
330 | DixReadAccess(1<<0)))) { | |||
331 | client->errorValue = syncObject; | |||
332 | return rc; | |||
333 | } | |||
334 | if (pSync != pTrigger->pSync) { /* new counter for trigger */ | |||
335 | SyncDeleteTriggerFromSyncObject(pTrigger); | |||
336 | pTrigger->pSync = pSync; | |||
337 | newSyncObject = TRUE1; | |||
338 | } | |||
339 | } | |||
340 | ||||
341 | /* if system counter, ask it what the current value is */ | |||
342 | ||||
343 | if (pSync && SYNC_COUNTER0 == pSync->type) { | |||
344 | pCounter = (SyncCounter *) pSync; | |||
345 | ||||
346 | if (IsSystemCounter(pCounter)(pCounter && (pCounter->sync.client == ((void*)0)) )) { | |||
347 | (*pCounter->pSysCounterInfo->QueryValue) ((void *) pCounter, | |||
348 | &pCounter->value); | |||
349 | } | |||
350 | } | |||
351 | ||||
352 | if (changes & XSyncCAValueType(1L<<1)) { | |||
353 | if (pTrigger->value_type != XSyncRelative && | |||
354 | pTrigger->value_type != XSyncAbsolute) { | |||
355 | client->errorValue = pTrigger->value_type; | |||
356 | return BadValue2; | |||
357 | } | |||
358 | } | |||
359 | ||||
360 | if (changes & XSyncCATestType(1L<<3)) { | |||
361 | ||||
362 | if (pSync && SYNC_FENCE1 == pSync->type) { | |||
363 | pTrigger->CheckTrigger = SyncCheckTriggerFence; | |||
364 | } | |||
365 | else { | |||
366 | /* select appropriate CheckTrigger function */ | |||
367 | ||||
368 | switch (pTrigger->test_type) { | |||
369 | case XSyncPositiveTransition: | |||
370 | pTrigger->CheckTrigger = SyncCheckTriggerPositiveTransition; | |||
371 | break; | |||
372 | case XSyncNegativeTransition: | |||
373 | pTrigger->CheckTrigger = SyncCheckTriggerNegativeTransition; | |||
374 | break; | |||
375 | case XSyncPositiveComparison: | |||
376 | pTrigger->CheckTrigger = SyncCheckTriggerPositiveComparison; | |||
377 | break; | |||
378 | case XSyncNegativeComparison: | |||
379 | pTrigger->CheckTrigger = SyncCheckTriggerNegativeComparison; | |||
380 | break; | |||
381 | default: | |||
382 | client->errorValue = pTrigger->test_type; | |||
383 | return BadValue2; | |||
384 | } | |||
385 | } | |||
386 | } | |||
387 | ||||
388 | if (changes & (XSyncCAValueType(1L<<1) | XSyncCAValue(1L<<2))) { | |||
389 | if (pTrigger->value_type == XSyncAbsolute) | |||
390 | pTrigger->test_value = pTrigger->wait_value; | |||
391 | else { /* relative */ | |||
392 | ||||
393 | Bool overflow; | |||
394 | ||||
395 | if (pCounter == NULL((void*)0)) | |||
396 | return BadMatch8; | |||
397 | ||||
398 | XSyncValueAdd(&pTrigger->test_value, pCounter->value,{ int t = (pCounter->value).lo; Bool signa = (((pCounter-> value).hi & 0x80000000) ? 1 : 0); Bool signb = (((pTrigger ->wait_value).hi & 0x80000000) ? 1 : 0); ((&pTrigger ->test_value)->lo = (pCounter->value).lo + (pTrigger ->wait_value).lo); ((&pTrigger->test_value)->hi = (pCounter->value).hi + (pTrigger->wait_value).hi); if ( t>(&pTrigger->test_value)->lo) (&pTrigger-> test_value)->hi++; *&overflow = ((signa == signb) && !(signa == (((*&pTrigger->test_value).hi & 0x80000000 ) ? 1 : 0))); } | |||
399 | pTrigger->wait_value, &overflow){ int t = (pCounter->value).lo; Bool signa = (((pCounter-> value).hi & 0x80000000) ? 1 : 0); Bool signb = (((pTrigger ->wait_value).hi & 0x80000000) ? 1 : 0); ((&pTrigger ->test_value)->lo = (pCounter->value).lo + (pTrigger ->wait_value).lo); ((&pTrigger->test_value)->hi = (pCounter->value).hi + (pTrigger->wait_value).hi); if ( t>(&pTrigger->test_value)->lo) (&pTrigger-> test_value)->hi++; *&overflow = ((signa == signb) && !(signa == (((*&pTrigger->test_value).hi & 0x80000000 ) ? 1 : 0))); }; | |||
400 | if (overflow) { | |||
401 | client->errorValue = XSyncValueHigh32(pTrigger->wait_value)((pTrigger->wait_value).hi); | |||
402 | return BadValue2; | |||
403 | } | |||
404 | } | |||
405 | } | |||
406 | ||||
407 | /* we wait until we're sure there are no errors before registering | |||
408 | * a new counter on a trigger | |||
409 | */ | |||
410 | if (newSyncObject) { | |||
411 | if ((rc = SyncAddTriggerToSyncObject(pTrigger)) != Success0) | |||
412 | return rc; | |||
413 | } | |||
414 | else if (pCounter && IsSystemCounter(pCounter)(pCounter && (pCounter->sync.client == ((void*)0)) )) { | |||
415 | SyncComputeBracketValues(pCounter); | |||
416 | } | |||
417 | ||||
418 | return Success0; | |||
419 | } | |||
420 | ||||
421 | /* AlarmNotify events happen in response to actions taken on an Alarm or | |||
422 | * the counter used by the alarm. AlarmNotify may be sent to multiple | |||
423 | * clients. The alarm maintains a list of clients interested in events. | |||
424 | */ | |||
425 | static void | |||
426 | SyncSendAlarmNotifyEvents(SyncAlarm * pAlarm) | |||
427 | { | |||
428 | SyncAlarmClientList *pcl; | |||
429 | xSyncAlarmNotifyEvent ane; | |||
430 | SyncTrigger *pTrigger = &pAlarm->trigger; | |||
431 | SyncCounter *pCounter; | |||
432 | ||||
433 | if (!SyncCheckWarnIsCounter(pTrigger->pSync, WARN_INVALID_COUNTER_ALARM)) | |||
434 | return; | |||
435 | ||||
436 | pCounter = (SyncCounter *) pTrigger->pSync; | |||
437 | ||||
438 | UpdateCurrentTime(); | |||
439 | ||||
440 | ane = (xSyncAlarmNotifyEvent) { | |||
441 | .type = SyncEventBase + XSyncAlarmNotify1, | |||
442 | .kind = XSyncAlarmNotify1, | |||
443 | .alarm = pAlarm->alarm_id, | |||
444 | .alarm_value_hi = XSyncValueHigh32(pTrigger->test_value)((pTrigger->test_value).hi), | |||
445 | .alarm_value_lo = XSyncValueLow32(pTrigger->test_value)((pTrigger->test_value).lo), | |||
446 | .time = currentTime.milliseconds, | |||
447 | .state = pAlarm->state | |||
448 | }; | |||
449 | ||||
450 | if (pTrigger->pSync && SYNC_COUNTER0 == pTrigger->pSync->type) { | |||
451 | ane.counter_value_hi = XSyncValueHigh32(pCounter->value)((pCounter->value).hi); | |||
452 | ane.counter_value_lo = XSyncValueLow32(pCounter->value)((pCounter->value).lo); | |||
453 | } | |||
454 | else { | |||
455 | /* XXX what else can we do if there's no counter? */ | |||
456 | ane.counter_value_hi = ane.counter_value_lo = 0; | |||
457 | } | |||
458 | ||||
459 | /* send to owner */ | |||
460 | if (pAlarm->events) | |||
461 | WriteEventsToClient(pAlarm->client, 1, (xEvent *) &ane); | |||
462 | ||||
463 | /* send to other interested clients */ | |||
464 | for (pcl = pAlarm->pEventClients; pcl; pcl = pcl->next) | |||
465 | WriteEventsToClient(pcl->client, 1, (xEvent *) &ane); | |||
466 | } | |||
467 | ||||
468 | /* CounterNotify events only occur in response to an Await. The events | |||
469 | * go only to the Awaiting client. | |||
470 | */ | |||
471 | static void | |||
472 | SyncSendCounterNotifyEvents(ClientPtr client, SyncAwait ** ppAwait, | |||
473 | int num_events) | |||
474 | { | |||
475 | xSyncCounterNotifyEvent *pEvents, *pev; | |||
476 | int i; | |||
477 | ||||
478 | if (client->clientGone) | |||
479 | return; | |||
480 | pev = pEvents = calloc(num_events, sizeof(xSyncCounterNotifyEvent)); | |||
481 | if (!pEvents) | |||
482 | return; | |||
483 | UpdateCurrentTime(); | |||
484 | for (i = 0; i < num_events; i++, ppAwait++, pev++) { | |||
485 | SyncTrigger *pTrigger = &(*ppAwait)->trigger; | |||
486 | ||||
487 | pev->type = SyncEventBase + XSyncCounterNotify0; | |||
488 | pev->kind = XSyncCounterNotify0; | |||
489 | pev->counter = pTrigger->pSync->id; | |||
490 | pev->wait_value_lo = XSyncValueLow32(pTrigger->test_value)((pTrigger->test_value).lo); | |||
491 | pev->wait_value_hi = XSyncValueHigh32(pTrigger->test_value)((pTrigger->test_value).hi); | |||
492 | if (SYNC_COUNTER0 == pTrigger->pSync->type) { | |||
493 | SyncCounter *pCounter = (SyncCounter *) pTrigger->pSync; | |||
494 | ||||
495 | pev->counter_value_lo = XSyncValueLow32(pCounter->value)((pCounter->value).lo); | |||
496 | pev->counter_value_hi = XSyncValueHigh32(pCounter->value)((pCounter->value).hi); | |||
497 | } | |||
498 | else { | |||
499 | pev->counter_value_lo = 0; | |||
500 | pev->counter_value_hi = 0; | |||
501 | } | |||
502 | ||||
503 | pev->time = currentTime.milliseconds; | |||
504 | pev->count = num_events - i - 1; /* events remaining */ | |||
505 | pev->destroyed = pTrigger->pSync->beingDestroyed; | |||
506 | } | |||
507 | /* swapping will be taken care of by this */ | |||
508 | WriteEventsToClient(client, num_events, (xEvent *) pEvents); | |||
509 | free(pEvents); | |||
510 | } | |||
511 | ||||
512 | /* This function is called when an alarm's counter is destroyed. | |||
513 | * It is plugged into pTrigger->CounterDestroyed (for alarm triggers). | |||
514 | */ | |||
515 | static void | |||
516 | SyncAlarmCounterDestroyed(SyncTrigger * pTrigger) | |||
517 | { | |||
518 | SyncAlarm *pAlarm = (SyncAlarm *) pTrigger; | |||
519 | ||||
520 | pAlarm->state = XSyncAlarmInactive; | |||
521 | SyncSendAlarmNotifyEvents(pAlarm); | |||
522 | pTrigger->pSync = NULL((void*)0); | |||
523 | } | |||
524 | ||||
525 | /* This function is called when an alarm "goes off." | |||
526 | * It is plugged into pTrigger->TriggerFired (for alarm triggers). | |||
527 | */ | |||
528 | static void | |||
529 | SyncAlarmTriggerFired(SyncTrigger * pTrigger) | |||
530 | { | |||
531 | SyncAlarm *pAlarm = (SyncAlarm *) pTrigger; | |||
532 | SyncCounter *pCounter; | |||
533 | CARD64XSyncValue new_test_value; | |||
534 | ||||
535 | if (!SyncCheckWarnIsCounter(pTrigger->pSync, WARN_INVALID_COUNTER_ALARM)) | |||
536 | return; | |||
537 | ||||
538 | pCounter = (SyncCounter *) pTrigger->pSync; | |||
539 | ||||
540 | /* no need to check alarm unless it's active */ | |||
541 | if (pAlarm->state != XSyncAlarmActive) | |||
542 | return; | |||
543 | ||||
544 | /* " if the counter value is None, or if the delta is 0 and | |||
545 | * the test-type is PositiveComparison or NegativeComparison, | |||
546 | * no change is made to value (test-value) and the alarm | |||
547 | * state is changed to Inactive before the event is generated." | |||
548 | */ | |||
549 | if (pCounter == NULL((void*)0) || (XSyncValueIsZero(pAlarm->delta)((pAlarm->delta).lo==0 && (pAlarm->delta).hi==0 ) | |||
550 | && (pAlarm->trigger.test_type == | |||
551 | XSyncPositiveComparison || | |||
552 | pAlarm->trigger.test_type == | |||
553 | XSyncNegativeComparison))) | |||
554 | pAlarm->state = XSyncAlarmInactive; | |||
555 | ||||
556 | new_test_value = pAlarm->trigger.test_value; | |||
557 | ||||
558 | if (pAlarm->state == XSyncAlarmActive) { | |||
559 | Bool overflow; | |||
560 | CARD64XSyncValue oldvalue; | |||
561 | SyncTrigger *paTrigger = &pAlarm->trigger; | |||
562 | SyncCounter *paCounter; | |||
563 | ||||
564 | if (!SyncCheckWarnIsCounter(paTrigger->pSync, | |||
565 | WARN_INVALID_COUNTER_ALARM)) | |||
566 | return; | |||
567 | ||||
568 | paCounter = (SyncCounter *) pTrigger->pSync; | |||
569 | ||||
570 | /* "The alarm is updated by repeatedly adding delta to the | |||
571 | * value of the trigger and re-initializing it until it | |||
572 | * becomes FALSE." | |||
573 | */ | |||
574 | oldvalue = paTrigger->test_value; | |||
575 | ||||
576 | /* XXX really should do something smarter here */ | |||
577 | ||||
578 | do { | |||
579 | XSyncValueAdd(&paTrigger->test_value, paTrigger->test_value,{ int t = (paTrigger->test_value).lo; Bool signa = (((paTrigger ->test_value).hi & 0x80000000) ? 1 : 0); Bool signb = ( ((pAlarm->delta).hi & 0x80000000) ? 1 : 0); ((&paTrigger ->test_value)->lo = (paTrigger->test_value).lo + (pAlarm ->delta).lo); ((&paTrigger->test_value)->hi = (paTrigger ->test_value).hi + (pAlarm->delta).hi); if (t>(& paTrigger->test_value)->lo) (&paTrigger->test_value )->hi++; *&overflow = ((signa == signb) && !(signa == (((*&paTrigger->test_value).hi & 0x80000000) ? 1 : 0))); } | |||
580 | pAlarm->delta, &overflow){ int t = (paTrigger->test_value).lo; Bool signa = (((paTrigger ->test_value).hi & 0x80000000) ? 1 : 0); Bool signb = ( ((pAlarm->delta).hi & 0x80000000) ? 1 : 0); ((&paTrigger ->test_value)->lo = (paTrigger->test_value).lo + (pAlarm ->delta).lo); ((&paTrigger->test_value)->hi = (paTrigger ->test_value).hi + (pAlarm->delta).hi); if (t>(& paTrigger->test_value)->lo) (&paTrigger->test_value )->hi++; *&overflow = ((signa == signb) && !(signa == (((*&paTrigger->test_value).hi & 0x80000000) ? 1 : 0))); }; | |||
581 | } while (!overflow && | |||
582 | (*paTrigger->CheckTrigger) (paTrigger, paCounter->value)); | |||
583 | ||||
584 | new_test_value = paTrigger->test_value; | |||
585 | paTrigger->test_value = oldvalue; | |||
586 | ||||
587 | /* "If this update would cause value to fall outside the range | |||
588 | * for an INT64...no change is made to value (test-value) and | |||
589 | * the alarm state is changed to Inactive before the event is | |||
590 | * generated." | |||
591 | */ | |||
592 | if (overflow) { | |||
593 | new_test_value = oldvalue; | |||
594 | pAlarm->state = XSyncAlarmInactive; | |||
595 | } | |||
596 | } | |||
597 | /* The AlarmNotify event has to have the "new state of the alarm" | |||
598 | * which we can't be sure of until this point. However, it has | |||
599 | * to have the "old" trigger test value. That's the reason for | |||
600 | * all the newvalue/oldvalue shuffling above. After we send the | |||
601 | * events, give the trigger its new test value. | |||
602 | */ | |||
603 | SyncSendAlarmNotifyEvents(pAlarm); | |||
604 | pTrigger->test_value = new_test_value; | |||
605 | } | |||
606 | ||||
607 | /* This function is called when an Await unblocks, either as a result | |||
608 | * of the trigger firing OR the counter being destroyed. | |||
609 | * It goes into pTrigger->TriggerFired AND pTrigger->CounterDestroyed | |||
610 | * (for Await triggers). | |||
611 | */ | |||
612 | static void | |||
613 | SyncAwaitTriggerFired(SyncTrigger * pTrigger) | |||
614 | { | |||
615 | SyncAwait *pAwait = (SyncAwait *) pTrigger; | |||
616 | int numwaits; | |||
617 | SyncAwaitUnion *pAwaitUnion; | |||
618 | SyncAwait **ppAwait; | |||
619 | int num_events = 0; | |||
620 | ||||
621 | pAwaitUnion = (SyncAwaitUnion *) pAwait->pHeader; | |||
622 | numwaits = pAwaitUnion->header.num_waitconditions; | |||
623 | ppAwait = xallocarray(numwaits, sizeof(SyncAwait *))xreallocarray(((void*)0), (numwaits), (sizeof(SyncAwait *))); | |||
624 | if (!ppAwait) | |||
625 | goto bail; | |||
626 | ||||
627 | pAwait = &(pAwaitUnion + 1)->await; | |||
628 | ||||
629 | /* "When a client is unblocked, all the CounterNotify events for | |||
630 | * the Await request are generated contiguously. If count is 0 | |||
631 | * there are no more events to follow for this request. If | |||
632 | * count is n, there are at least n more events to follow." | |||
633 | * | |||
634 | * Thus, it is best to find all the counters for which events | |||
635 | * need to be sent first, so that an accurate count field can | |||
636 | * be stored in the events. | |||
637 | */ | |||
638 | for (; numwaits; numwaits--, pAwait++) { | |||
639 | CARD64XSyncValue diff; | |||
640 | Bool overflow, diffgreater, diffequal; | |||
641 | ||||
642 | /* "A CounterNotify event with the destroyed flag set to TRUE is | |||
643 | * always generated if the counter for one of the triggers is | |||
644 | * destroyed." | |||
645 | */ | |||
646 | if (pAwait->trigger.pSync->beingDestroyed) { | |||
647 | ppAwait[num_events++] = pAwait; | |||
648 | continue; | |||
649 | } | |||
650 | ||||
651 | if (SYNC_COUNTER0 == pAwait->trigger.pSync->type) { | |||
652 | SyncCounter *pCounter = (SyncCounter *) pAwait->trigger.pSync; | |||
653 | ||||
654 | /* "The difference between the counter and the test value is | |||
655 | * calculated by subtracting the test value from the value of | |||
656 | * the counter." | |||
657 | */ | |||
658 | XSyncValueSubtract(&diff, pCounter->value,{ int t = (pCounter->value).lo; Bool signa = (((pCounter-> value).hi & 0x80000000) ? 1 : 0); Bool signb = (((pAwait-> trigger.test_value).hi & 0x80000000) ? 1 : 0); ((&diff )->lo = (pCounter->value).lo - (pAwait->trigger.test_value ).lo); ((&diff)->hi = (pCounter->value).hi - (pAwait ->trigger.test_value).hi); if (t<(&diff)->lo) (& diff)->hi--; *&overflow = ((signa == signb) && !(signa == (((*&diff).hi & 0x80000000) ? 1 : 0))); } | |||
659 | pAwait->trigger.test_value, &overflow){ int t = (pCounter->value).lo; Bool signa = (((pCounter-> value).hi & 0x80000000) ? 1 : 0); Bool signb = (((pAwait-> trigger.test_value).hi & 0x80000000) ? 1 : 0); ((&diff )->lo = (pCounter->value).lo - (pAwait->trigger.test_value ).lo); ((&diff)->hi = (pCounter->value).hi - (pAwait ->trigger.test_value).hi); if (t<(&diff)->lo) (& diff)->hi--; *&overflow = ((signa == signb) && !(signa == (((*&diff).hi & 0x80000000) ? 1 : 0))); }; | |||
660 | ||||
661 | /* "If the difference lies outside the range for an INT64, an | |||
662 | * event is not generated." | |||
663 | */ | |||
664 | if (overflow) | |||
665 | continue; | |||
666 | diffgreater = XSyncValueGreaterThan(diff, pAwait->event_threshold)((diff).hi>(pAwait->event_threshold).hi || ((diff).hi== (pAwait->event_threshold).hi && (diff).lo>(pAwait ->event_threshold).lo)); | |||
667 | diffequal = XSyncValueEqual(diff, pAwait->event_threshold)((diff).lo==(pAwait->event_threshold).lo && (diff) .hi==(pAwait->event_threshold).hi); | |||
668 | ||||
669 | /* "If the test-type is PositiveTransition or | |||
670 | * PositiveComparison, a CounterNotify event is generated if | |||
671 | * the difference is at least event-threshold. If the test-type | |||
672 | * is NegativeTransition or NegativeComparison, a CounterNotify | |||
673 | * event is generated if the difference is at most | |||
674 | * event-threshold." | |||
675 | */ | |||
676 | ||||
677 | if (((pAwait->trigger.test_type == XSyncPositiveComparison || | |||
678 | pAwait->trigger.test_type == XSyncPositiveTransition) | |||
679 | && (diffgreater || diffequal)) | |||
680 | || | |||
681 | ((pAwait->trigger.test_type == XSyncNegativeComparison || | |||
682 | pAwait->trigger.test_type == XSyncNegativeTransition) | |||
683 | && (!diffgreater) /* less or equal */ | |||
684 | ) | |||
685 | ) { | |||
686 | ppAwait[num_events++] = pAwait; | |||
687 | } | |||
688 | } | |||
689 | } | |||
690 | if (num_events) | |||
691 | SyncSendCounterNotifyEvents(pAwaitUnion->header.client, ppAwait, | |||
692 | num_events); | |||
693 | free(ppAwait); | |||
694 | ||||
695 | bail: | |||
696 | /* unblock the client */ | |||
697 | AttendClient(pAwaitUnion->header.client); | |||
698 | /* delete the await */ | |||
699 | FreeResource(pAwaitUnion->header.delete_id, RT_NONE((RESTYPE)0)); | |||
700 | } | |||
701 | ||||
702 | static CARD64XSyncValue | |||
703 | SyncUpdateCounter(SyncCounter *pCounter, CARD64XSyncValue newval) | |||
704 | { | |||
705 | CARD64XSyncValue oldval = pCounter->value; | |||
706 | pCounter->value = newval; | |||
707 | return oldval; | |||
708 | } | |||
709 | ||||
710 | /* This function should always be used to change a counter's value so that | |||
711 | * any triggers depending on the counter will be checked. | |||
712 | */ | |||
713 | void | |||
714 | SyncChangeCounter(SyncCounter * pCounter, CARD64XSyncValue newval) | |||
715 | { | |||
716 | SyncTriggerList *ptl, *pnext; | |||
717 | CARD64XSyncValue oldval; | |||
718 | ||||
719 | oldval = SyncUpdateCounter(pCounter, newval); | |||
720 | ||||
721 | /* run through triggers to see if any become true */ | |||
722 | for (ptl = pCounter->sync.pTriglist; ptl; ptl = pnext) { | |||
723 | pnext = ptl->next; | |||
724 | if ((*ptl->pTrigger->CheckTrigger) (ptl->pTrigger, oldval)) | |||
725 | (*ptl->pTrigger->TriggerFired) (ptl->pTrigger); | |||
726 | } | |||
727 | ||||
728 | if (IsSystemCounter(pCounter)(pCounter && (pCounter->sync.client == ((void*)0)) )) { | |||
729 | SyncComputeBracketValues(pCounter); | |||
730 | } | |||
731 | } | |||
732 | ||||
733 | /* loosely based on dix/events.c/EventSelectForWindow */ | |||
734 | static Bool | |||
735 | SyncEventSelectForAlarm(SyncAlarm * pAlarm, ClientPtr client, Bool wantevents) | |||
736 | { | |||
737 | SyncAlarmClientList *pClients; | |||
738 | ||||
739 | if (client == pAlarm->client) { /* alarm owner */ | |||
740 | pAlarm->events = wantevents; | |||
741 | return Success0; | |||
742 | } | |||
743 | ||||
744 | /* see if the client is already on the list (has events selected) */ | |||
745 | ||||
746 | for (pClients = pAlarm->pEventClients; pClients; pClients = pClients->next) { | |||
747 | if (pClients->client == client) { | |||
748 | /* client's presence on the list indicates desire for | |||
749 | * events. If the client doesn't want events, remove it | |||
750 | * from the list. If the client does want events, do | |||
751 | * nothing, since it's already got them. | |||
752 | */ | |||
753 | if (!wantevents) { | |||
754 | FreeResource(pClients->delete_id, RT_NONE((RESTYPE)0)); | |||
755 | } | |||
756 | return Success0; | |||
757 | } | |||
758 | } | |||
759 | ||||
760 | /* if we get here, this client does not currently have | |||
761 | * events selected on the alarm | |||
762 | */ | |||
763 | ||||
764 | if (!wantevents) | |||
765 | /* client doesn't want events, and we just discovered that it | |||
766 | * doesn't have them, so there's nothing to do. | |||
767 | */ | |||
768 | return Success0; | |||
769 | ||||
770 | /* add new client to pAlarm->pEventClients */ | |||
771 | ||||
772 | pClients = malloc(sizeof(SyncAlarmClientList)); | |||
773 | if (!pClients) | |||
774 | return BadAlloc11; | |||
775 | ||||
776 | /* register it as a resource so it will be cleaned up | |||
777 | * if the client dies | |||
778 | */ | |||
779 | ||||
780 | pClients->delete_id = FakeClientID(client->index); | |||
781 | ||||
782 | /* link it into list after we know all the allocations succeed */ | |||
783 | pClients->next = pAlarm->pEventClients; | |||
784 | pAlarm->pEventClients = pClients; | |||
785 | pClients->client = client; | |||
786 | ||||
787 | if (!AddResourceDarwin_X_AddResource(pClients->delete_id, RTAlarmClient, pAlarm)) | |||
788 | return BadAlloc11; | |||
789 | ||||
790 | return Success0; | |||
791 | } | |||
792 | ||||
793 | /* | |||
794 | * ** SyncChangeAlarmAttributes ** This is used by CreateAlarm and ChangeAlarm | |||
795 | */ | |||
796 | static int | |||
797 | SyncChangeAlarmAttributes(ClientPtr client, SyncAlarm * pAlarm, Mask mask, | |||
798 | CARD32 *values) | |||
799 | { | |||
800 | int status; | |||
801 | XSyncCounter counter; | |||
802 | Mask origmask = mask; | |||
803 | ||||
804 | counter = pAlarm->trigger.pSync ? pAlarm->trigger.pSync->id : None0L; | |||
805 | ||||
806 | while (mask) { | |||
807 | int index2 = lowbit(mask)((mask) & (~(mask) + 1)); | |||
808 | ||||
809 | mask &= ~index2; | |||
810 | switch (index2) { | |||
811 | case XSyncCACounter(1L<<0): | |||
812 | mask &= ~XSyncCACounter(1L<<0); | |||
813 | /* sanity check in SyncInitTrigger */ | |||
814 | counter = *values++; | |||
815 | break; | |||
816 | ||||
817 | case XSyncCAValueType(1L<<1): | |||
818 | mask &= ~XSyncCAValueType(1L<<1); | |||
819 | /* sanity check in SyncInitTrigger */ | |||
820 | pAlarm->trigger.value_type = *values++; | |||
821 | break; | |||
822 | ||||
823 | case XSyncCAValue(1L<<2): | |||
824 | mask &= ~XSyncCAValue(1L<<2); | |||
825 | XSyncIntsToValue(&pAlarm->trigger.wait_value, values[1], values[0])((&pAlarm->trigger.wait_value)->lo = (values[1]), ( &pAlarm->trigger.wait_value)->hi = (values[0])); | |||
826 | values += 2; | |||
827 | break; | |||
828 | ||||
829 | case XSyncCATestType(1L<<3): | |||
830 | mask &= ~XSyncCATestType(1L<<3); | |||
831 | /* sanity check in SyncInitTrigger */ | |||
832 | pAlarm->trigger.test_type = *values++; | |||
833 | break; | |||
834 | ||||
835 | case XSyncCADelta(1L<<4): | |||
836 | mask &= ~XSyncCADelta(1L<<4); | |||
837 | XSyncIntsToValue(&pAlarm->delta, values[1], values[0])((&pAlarm->delta)->lo = (values[1]), (&pAlarm-> delta)->hi = (values[0])); | |||
838 | values += 2; | |||
839 | break; | |||
840 | ||||
841 | case XSyncCAEvents(1L<<5): | |||
842 | mask &= ~XSyncCAEvents(1L<<5); | |||
843 | if ((*values != xTrue1) && (*values != xFalse0)) { | |||
844 | client->errorValue = *values; | |||
845 | return BadValue2; | |||
846 | } | |||
847 | status = SyncEventSelectForAlarm(pAlarm, client, | |||
848 | (Bool) (*values++)); | |||
849 | if (status != Success0) | |||
850 | return status; | |||
851 | break; | |||
852 | ||||
853 | default: | |||
854 | client->errorValue = mask; | |||
855 | return BadValue2; | |||
856 | } | |||
857 | } | |||
858 | ||||
859 | /* "If the test-type is PositiveComparison or PositiveTransition | |||
860 | * and delta is less than zero, or if the test-type is | |||
861 | * NegativeComparison or NegativeTransition and delta is | |||
862 | * greater than zero, a Match error is generated." | |||
863 | */ | |||
864 | if (origmask & (XSyncCADelta(1L<<4) | XSyncCATestType(1L<<3))) { | |||
865 | CARD64XSyncValue zero; | |||
866 | ||||
867 | XSyncIntToValue(&zero, 0)((&zero)->hi=((0<0)?~0:0),(&zero)->lo=(0)); | |||
868 | if ((((pAlarm->trigger.test_type == XSyncPositiveComparison) || | |||
869 | (pAlarm->trigger.test_type == XSyncPositiveTransition)) | |||
870 | && XSyncValueLessThan(pAlarm->delta, zero)((pAlarm->delta).hi<(zero).hi || ((pAlarm->delta).hi ==(zero).hi && (pAlarm->delta).lo<(zero).lo))) | |||
871 | || | |||
872 | (((pAlarm->trigger.test_type == XSyncNegativeComparison) || | |||
873 | (pAlarm->trigger.test_type == XSyncNegativeTransition)) | |||
874 | && XSyncValueGreaterThan(pAlarm->delta, zero)((pAlarm->delta).hi>(zero).hi || ((pAlarm->delta).hi ==(zero).hi && (pAlarm->delta).lo>(zero).lo))) | |||
875 | ) { | |||
876 | return BadMatch8; | |||
877 | } | |||
878 | } | |||
879 | ||||
880 | /* postpone this until now, when we're sure nothing else can go wrong */ | |||
881 | if ((status = SyncInitTrigger(client, &pAlarm->trigger, counter, RTCounter, | |||
882 | origmask & XSyncCAAllTrigger((1L<<0) | (1L<<1) | (1L<<2) | (1L<<3 )))) != Success0) | |||
883 | return status; | |||
884 | ||||
885 | /* XXX spec does not really say to do this - needs clarification */ | |||
886 | pAlarm->state = XSyncAlarmActive; | |||
887 | return Success0; | |||
888 | } | |||
889 | ||||
890 | static SyncObject * | |||
891 | SyncCreate(ClientPtr client, XID id, unsigned char type) | |||
892 | { | |||
893 | SyncObject *pSync; | |||
894 | ||||
895 | switch (type) { | |||
896 | case SYNC_COUNTER0: | |||
897 | pSync = malloc(sizeof(SyncCounter)); | |||
898 | break; | |||
899 | case SYNC_FENCE1: | |||
900 | pSync = (SyncObject *) dixAllocateObjectWithPrivates(SyncFence,(SyncFence *) _dixAllocateObjectWithPrivates(sizeof(SyncFence ), sizeof(SyncFence), __builtin_offsetof(SyncFence, devPrivates ), PRIVATE_SYNC_FENCE) | |||
901 | PRIVATE_SYNC_FENCE)(SyncFence *) _dixAllocateObjectWithPrivates(sizeof(SyncFence ), sizeof(SyncFence), __builtin_offsetof(SyncFence, devPrivates ), PRIVATE_SYNC_FENCE); | |||
902 | break; | |||
903 | default: | |||
904 | return NULL((void*)0); | |||
905 | } | |||
906 | ||||
907 | if (!pSync) | |||
908 | return NULL((void*)0); | |||
909 | ||||
910 | pSync->client = client; | |||
911 | pSync->id = id; | |||
912 | pSync->pTriglist = NULL((void*)0); | |||
913 | pSync->beingDestroyed = FALSE0; | |||
914 | pSync->type = type; | |||
915 | ||||
916 | return pSync; | |||
917 | } | |||
918 | ||||
919 | int | |||
920 | SyncCreateFenceFromFD(ClientPtr client, DrawablePtr pDraw, XID id, int fd, BOOL initially_triggered) | |||
921 | { | |||
922 | #if HAVE_XSHMFENCE1 | |||
923 | SyncFence *pFence; | |||
924 | int status; | |||
925 | ||||
926 | pFence = (SyncFence *) SyncCreate(client, id, SYNC_FENCE1); | |||
927 | if (!pFence) | |||
928 | return BadAlloc11; | |||
929 | ||||
930 | status = miSyncInitFenceFromFD(pDraw, pFence, fd, initially_triggered); | |||
931 | if (status != Success0) { | |||
932 | dixFreeObjectWithPrivates(pFence, PRIVATE_SYNC_FENCE)_dixFreeObjectWithPrivates(pFence, (pFence)->devPrivates, PRIVATE_SYNC_FENCE ); | |||
933 | return status; | |||
934 | } | |||
935 | ||||
936 | if (!AddResourceDarwin_X_AddResource(id, RTFence, (void *) pFence)) | |||
937 | return BadAlloc11; | |||
938 | ||||
939 | return Success0; | |||
940 | #else | |||
941 | return BadImplementation17; | |||
942 | #endif | |||
943 | } | |||
944 | ||||
945 | int | |||
946 | SyncFDFromFence(ClientPtr client, DrawablePtr pDraw, SyncFence *pFence) | |||
947 | { | |||
948 | #if HAVE_XSHMFENCE1 | |||
949 | return miSyncFDFromFence(pDraw, pFence); | |||
950 | #else | |||
951 | return BadImplementation17; | |||
952 | #endif | |||
953 | } | |||
954 | ||||
955 | static SyncCounter * | |||
956 | SyncCreateCounter(ClientPtr client, XSyncCounter id, CARD64XSyncValue initialvalue) | |||
957 | { | |||
958 | SyncCounter *pCounter; | |||
959 | ||||
960 | if (!(pCounter = (SyncCounter *) SyncCreate(client, id, SYNC_COUNTER0))) | |||
961 | return NULL((void*)0); | |||
962 | ||||
963 | pCounter->value = initialvalue; | |||
964 | pCounter->pSysCounterInfo = NULL((void*)0); | |||
965 | ||||
966 | if (!AddResourceDarwin_X_AddResource(id, RTCounter, (void *) pCounter)) | |||
967 | return NULL((void*)0); | |||
968 | ||||
969 | return pCounter; | |||
970 | } | |||
971 | ||||
972 | static int FreeCounter(void *, XID); | |||
973 | ||||
974 | /* | |||
975 | * ***** System Counter utilities | |||
976 | */ | |||
977 | ||||
978 | SyncCounter* | |||
979 | SyncCreateSystemCounter(const char *name, | |||
980 | CARD64XSyncValue initial, | |||
981 | CARD64XSyncValue resolution, | |||
982 | SyncCounterType counterType, | |||
983 | SyncSystemCounterQueryValue QueryValue, | |||
984 | SyncSystemCounterBracketValues BracketValues | |||
985 | ) | |||
986 | { | |||
987 | SyncCounter *pCounter = SyncCreateCounter(NULL((void*)0), FakeClientID(0), initial); | |||
988 | ||||
989 | if (pCounter) { | |||
990 | SysCounterInfo *psci; | |||
991 | ||||
992 | psci = malloc(sizeof(SysCounterInfo)); | |||
993 | if (!psci) { | |||
994 | FreeResource(pCounter->sync.id, RT_NONE((RESTYPE)0)); | |||
995 | return pCounter; | |||
996 | } | |||
997 | pCounter->pSysCounterInfo = psci; | |||
998 | psci->pCounter = pCounter; | |||
999 | psci->name = strdup(name); | |||
1000 | psci->resolution = resolution; | |||
1001 | psci->counterType = counterType; | |||
1002 | psci->QueryValue = QueryValue; | |||
1003 | psci->BracketValues = BracketValues; | |||
1004 | psci->private = NULL((void*)0); | |||
1005 | XSyncMaxValue(&psci->bracket_greater)((&psci->bracket_greater)->hi = 0x7fffffff, (&psci ->bracket_greater)->lo = 0xffffffff); | |||
1006 | XSyncMinValue(&psci->bracket_less)((&psci->bracket_less)->hi = 0x80000000, (&psci ->bracket_less)->lo = 0); | |||
1007 | xorg_list_add(&psci->entry, &SysCounterList); | |||
1008 | } | |||
1009 | return pCounter; | |||
1010 | } | |||
1011 | ||||
1012 | void | |||
1013 | SyncDestroySystemCounter(void *pSysCounter) | |||
1014 | { | |||
1015 | SyncCounter *pCounter = (SyncCounter *) pSysCounter; | |||
1016 | ||||
1017 | FreeResource(pCounter->sync.id, RT_NONE((RESTYPE)0)); | |||
1018 | } | |||
1019 | ||||
1020 | static void | |||
1021 | SyncComputeBracketValues(SyncCounter * pCounter) | |||
1022 | { | |||
1023 | SyncTriggerList *pCur; | |||
1024 | SyncTrigger *pTrigger; | |||
1025 | SysCounterInfo *psci; | |||
1026 | CARD64XSyncValue *pnewgtval = NULL((void*)0); | |||
1027 | CARD64XSyncValue *pnewltval = NULL((void*)0); | |||
1028 | SyncCounterType ct; | |||
1029 | ||||
1030 | if (!pCounter) | |||
1031 | return; | |||
1032 | ||||
1033 | psci = pCounter->pSysCounterInfo; | |||
1034 | ct = pCounter->pSysCounterInfo->counterType; | |||
1035 | if (ct == XSyncCounterNeverChanges) | |||
1036 | return; | |||
1037 | ||||
1038 | XSyncMaxValue(&psci->bracket_greater)((&psci->bracket_greater)->hi = 0x7fffffff, (&psci ->bracket_greater)->lo = 0xffffffff); | |||
1039 | XSyncMinValue(&psci->bracket_less)((&psci->bracket_less)->hi = 0x80000000, (&psci ->bracket_less)->lo = 0); | |||
1040 | ||||
1041 | for (pCur = pCounter->sync.pTriglist; pCur; pCur = pCur->next) { | |||
1042 | pTrigger = pCur->pTrigger; | |||
1043 | ||||
1044 | if (pTrigger->test_type == XSyncPositiveComparison && | |||
1045 | ct != XSyncCounterNeverIncreases) { | |||
1046 | if (XSyncValueLessThan(pCounter->value, pTrigger->test_value)((pCounter->value).hi<(pTrigger->test_value).hi || ( (pCounter->value).hi==(pTrigger->test_value).hi && (pCounter->value).lo<(pTrigger->test_value).lo)) && | |||
1047 | XSyncValueLessThan(pTrigger->test_value,((pTrigger->test_value).hi<(psci->bracket_greater).hi || ((pTrigger->test_value).hi==(psci->bracket_greater) .hi && (pTrigger->test_value).lo<(psci->bracket_greater ).lo)) | |||
1048 | psci->bracket_greater)((pTrigger->test_value).hi<(psci->bracket_greater).hi || ((pTrigger->test_value).hi==(psci->bracket_greater) .hi && (pTrigger->test_value).lo<(psci->bracket_greater ).lo))) { | |||
1049 | psci->bracket_greater = pTrigger->test_value; | |||
1050 | pnewgtval = &psci->bracket_greater; | |||
1051 | } | |||
1052 | else if (XSyncValueGreaterThan(pCounter->value, pTrigger->test_value)((pCounter->value).hi>(pTrigger->test_value).hi || ( (pCounter->value).hi==(pTrigger->test_value).hi && (pCounter->value).lo>(pTrigger->test_value).lo)) && | |||
1053 | XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less)((pTrigger->test_value).hi>(psci->bracket_less).hi || ((pTrigger->test_value).hi==(psci->bracket_less).hi && (pTrigger->test_value).lo>(psci->bracket_less).lo))) { | |||
1054 | psci->bracket_less = pTrigger->test_value; | |||
1055 | pnewltval = &psci->bracket_less; | |||
1056 | } | |||
1057 | } | |||
1058 | else if (pTrigger->test_type == XSyncNegativeComparison && | |||
1059 | ct != XSyncCounterNeverDecreases) { | |||
1060 | if (XSyncValueGreaterThan(pCounter->value, pTrigger->test_value)((pCounter->value).hi>(pTrigger->test_value).hi || ( (pCounter->value).hi==(pTrigger->test_value).hi && (pCounter->value).lo>(pTrigger->test_value).lo)) && | |||
1061 | XSyncValueGreaterThan(pTrigger->test_value,((pTrigger->test_value).hi>(psci->bracket_less).hi || ((pTrigger->test_value).hi==(psci->bracket_less).hi && (pTrigger->test_value).lo>(psci->bracket_less).lo)) | |||
1062 | psci->bracket_less)((pTrigger->test_value).hi>(psci->bracket_less).hi || ((pTrigger->test_value).hi==(psci->bracket_less).hi && (pTrigger->test_value).lo>(psci->bracket_less).lo))) { | |||
1063 | psci->bracket_less = pTrigger->test_value; | |||
1064 | pnewltval = &psci->bracket_less; | |||
1065 | } | |||
1066 | else if (XSyncValueLessThan(pCounter->value, pTrigger->test_value)((pCounter->value).hi<(pTrigger->test_value).hi || ( (pCounter->value).hi==(pTrigger->test_value).hi && (pCounter->value).lo<(pTrigger->test_value).lo)) && | |||
1067 | XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater)((pTrigger->test_value).hi<(psci->bracket_greater).hi || ((pTrigger->test_value).hi==(psci->bracket_greater) .hi && (pTrigger->test_value).lo<(psci->bracket_greater ).lo))) { | |||
1068 | psci->bracket_greater = pTrigger->test_value; | |||
1069 | pnewgtval = &psci->bracket_greater; | |||
1070 | } | |||
1071 | } | |||
1072 | else if (pTrigger->test_type == XSyncNegativeTransition && | |||
1073 | ct != XSyncCounterNeverIncreases) { | |||
1074 | if (XSyncValueGreaterOrEqual(pCounter->value, pTrigger->test_value)((pCounter->value).hi>(pTrigger->test_value).hi || ( (pCounter->value).hi==(pTrigger->test_value).hi && (pCounter->value).lo>=(pTrigger->test_value).lo)) && | |||
1075 | XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less)((pTrigger->test_value).hi>(psci->bracket_less).hi || ((pTrigger->test_value).hi==(psci->bracket_less).hi && (pTrigger->test_value).lo>(psci->bracket_less).lo))) { | |||
1076 | /* | |||
1077 | * If the value is exactly equal to our threshold, we want one | |||
1078 | * more event in the negative direction to ensure we pick up | |||
1079 | * when the value is less than this threshold. | |||
1080 | */ | |||
1081 | psci->bracket_less = pTrigger->test_value; | |||
1082 | pnewltval = &psci->bracket_less; | |||
1083 | } | |||
1084 | else if (XSyncValueLessThan(pCounter->value, pTrigger->test_value)((pCounter->value).hi<(pTrigger->test_value).hi || ( (pCounter->value).hi==(pTrigger->test_value).hi && (pCounter->value).lo<(pTrigger->test_value).lo)) && | |||
1085 | XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater)((pTrigger->test_value).hi<(psci->bracket_greater).hi || ((pTrigger->test_value).hi==(psci->bracket_greater) .hi && (pTrigger->test_value).lo<(psci->bracket_greater ).lo))) { | |||
1086 | psci->bracket_greater = pTrigger->test_value; | |||
1087 | pnewgtval = &psci->bracket_greater; | |||
1088 | } | |||
1089 | } | |||
1090 | else if (pTrigger->test_type == XSyncPositiveTransition && | |||
1091 | ct != XSyncCounterNeverDecreases) { | |||
1092 | if (XSyncValueLessOrEqual(pCounter->value, pTrigger->test_value)((pCounter->value).hi<(pTrigger->test_value).hi || ( (pCounter->value).hi==(pTrigger->test_value).hi && (pCounter->value).lo<=(pTrigger->test_value).lo)) && | |||
1093 | XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater)((pTrigger->test_value).hi<(psci->bracket_greater).hi || ((pTrigger->test_value).hi==(psci->bracket_greater) .hi && (pTrigger->test_value).lo<(psci->bracket_greater ).lo))) { | |||
1094 | /* | |||
1095 | * If the value is exactly equal to our threshold, we | |||
1096 | * want one more event in the positive direction to | |||
1097 | * ensure we pick up when the value *exceeds* this | |||
1098 | * threshold. | |||
1099 | */ | |||
1100 | psci->bracket_greater = pTrigger->test_value; | |||
1101 | pnewgtval = &psci->bracket_greater; | |||
1102 | } | |||
1103 | else if (XSyncValueGreaterThan(pCounter->value, pTrigger->test_value)((pCounter->value).hi>(pTrigger->test_value).hi || ( (pCounter->value).hi==(pTrigger->test_value).hi && (pCounter->value).lo>(pTrigger->test_value).lo)) && | |||
1104 | XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less)((pTrigger->test_value).hi>(psci->bracket_less).hi || ((pTrigger->test_value).hi==(psci->bracket_less).hi && (pTrigger->test_value).lo>(psci->bracket_less).lo))) { | |||
1105 | psci->bracket_less = pTrigger->test_value; | |||
1106 | pnewltval = &psci->bracket_less; | |||
1107 | } | |||
1108 | } | |||
1109 | } /* end for each trigger */ | |||
1110 | ||||
1111 | (*psci->BracketValues) ((void *) pCounter, pnewltval, pnewgtval); | |||
1112 | ||||
1113 | } | |||
1114 | ||||
1115 | /* | |||
1116 | * ***** Resource delete functions | |||
1117 | */ | |||
1118 | ||||
1119 | /* ARGSUSED */ | |||
1120 | static int | |||
1121 | FreeAlarm(void *addr, XID id) | |||
1122 | { | |||
1123 | SyncAlarm *pAlarm = (SyncAlarm *) addr; | |||
1124 | ||||
1125 | pAlarm->state = XSyncAlarmDestroyed; | |||
1126 | ||||
1127 | SyncSendAlarmNotifyEvents(pAlarm); | |||
1128 | ||||
1129 | /* delete event selections */ | |||
1130 | ||||
1131 | while (pAlarm->pEventClients) | |||
1132 | FreeResource(pAlarm->pEventClients->delete_id, RT_NONE((RESTYPE)0)); | |||
1133 | ||||
1134 | SyncDeleteTriggerFromSyncObject(&pAlarm->trigger); | |||
1135 | ||||
1136 | free(pAlarm); | |||
1137 | return Success0; | |||
1138 | } | |||
1139 | ||||
1140 | /* | |||
1141 | * ** Cleanup after the destruction of a Counter | |||
1142 | */ | |||
1143 | /* ARGSUSED */ | |||
1144 | static int | |||
1145 | FreeCounter(void *env, XID id) | |||
1146 | { | |||
1147 | SyncCounter *pCounter = (SyncCounter *) env; | |||
1148 | SyncTriggerList *ptl, *pnext; | |||
1149 | ||||
1150 | pCounter->sync.beingDestroyed = TRUE1; | |||
1151 | /* tell all the counter's triggers that the counter has been destroyed */ | |||
1152 | for (ptl = pCounter->sync.pTriglist; ptl; ptl = pnext) { | |||
1153 | (*ptl->pTrigger->CounterDestroyed) (ptl->pTrigger); | |||
1154 | pnext = ptl->next; | |||
1155 | free(ptl); /* destroy the trigger list as we go */ | |||
1156 | } | |||
1157 | if (IsSystemCounter(pCounter)(pCounter && (pCounter->sync.client == ((void*)0)) )) { | |||
1158 | xorg_list_del(&pCounter->pSysCounterInfo->entry); | |||
1159 | free(pCounter->pSysCounterInfo->name); | |||
1160 | free(pCounter->pSysCounterInfo->private); | |||
1161 | free(pCounter->pSysCounterInfo); | |||
1162 | } | |||
1163 | free(pCounter); | |||
1164 | return Success0; | |||
1165 | } | |||
1166 | ||||
1167 | /* | |||
1168 | * ** Cleanup after Await | |||
1169 | */ | |||
1170 | /* ARGSUSED */ | |||
1171 | static int | |||
1172 | FreeAwait(void *addr, XID id) | |||
1173 | { | |||
1174 | SyncAwaitUnion *pAwaitUnion = (SyncAwaitUnion *) addr; | |||
1175 | SyncAwait *pAwait; | |||
1176 | int numwaits; | |||
1177 | ||||
1178 | pAwait = &(pAwaitUnion + 1)->await; /* first await on list */ | |||
1179 | ||||
1180 | /* remove triggers from counters */ | |||
1181 | ||||
1182 | for (numwaits = pAwaitUnion->header.num_waitconditions; numwaits; | |||
1183 | numwaits--, pAwait++) { | |||
1184 | /* If the counter is being destroyed, FreeCounter will delete | |||
1185 | * the trigger list itself, so don't do it here. | |||
1186 | */ | |||
1187 | SyncObject *pSync = pAwait->trigger.pSync; | |||
1188 | ||||
1189 | if (pSync && !pSync->beingDestroyed) | |||
1190 | SyncDeleteTriggerFromSyncObject(&pAwait->trigger); | |||
1191 | } | |||
1192 | free(pAwaitUnion); | |||
1193 | return Success0; | |||
1194 | } | |||
1195 | ||||
1196 | /* loosely based on dix/events.c/OtherClientGone */ | |||
1197 | static int | |||
1198 | FreeAlarmClient(void *value, XID id) | |||
1199 | { | |||
1200 | SyncAlarm *pAlarm = (SyncAlarm *) value; | |||
1201 | SyncAlarmClientList *pCur, *pPrev; | |||
1202 | ||||
1203 | for (pPrev = NULL((void*)0), pCur = pAlarm->pEventClients; | |||
1204 | pCur; pPrev = pCur, pCur = pCur->next) { | |||
1205 | if (pCur->delete_id == id) { | |||
1206 | if (pPrev) | |||
1207 | pPrev->next = pCur->next; | |||
1208 | else | |||
1209 | pAlarm->pEventClients = pCur->next; | |||
1210 | free(pCur); | |||
1211 | return Success0; | |||
1212 | } | |||
1213 | } | |||
1214 | FatalError("alarm client not on event list"); | |||
1215 | /*NOTREACHED*/} | |||
1216 | ||||
1217 | /* | |||
1218 | * ***** Proc functions | |||
1219 | */ | |||
1220 | ||||
1221 | /* | |||
1222 | * ** Initialize the extension | |||
1223 | */ | |||
1224 | static int | |||
1225 | ProcSyncInitialize(ClientPtr client) | |||
1226 | { | |||
1227 | xSyncInitializeReply rep = { | |||
1228 | .type = X_Reply1, | |||
1229 | .sequenceNumber = client->sequence, | |||
1230 | .length = 0, | |||
1231 | .majorVersion = SERVER_SYNC_MAJOR_VERSION3, | |||
1232 | .minorVersion = SERVER_SYNC_MINOR_VERSION1, | |||
1233 | }; | |||
1234 | ||||
1235 | REQUEST_SIZE_MATCH(xSyncInitializeReq)if ((sizeof(xSyncInitializeReq) >> 2) != client->req_len ) return(16); | |||
1236 | ||||
1237 | if (client->swapped) { | |||
1238 | swaps(&rep.sequenceNumber)do { if (sizeof(*(&rep.sequenceNumber)) != 2) wrong_size( ); if (__builtin_constant_p((uintptr_t)(&rep.sequenceNumber ) & 1) && ((uintptr_t)(&rep.sequenceNumber) & 1) == 0) *(&rep.sequenceNumber) = lswaps(*(&rep.sequenceNumber )); else swap_uint16((uint16_t *)(&rep.sequenceNumber)); } while (0); | |||
1239 | } | |||
1240 | WriteToClient(client, sizeof(rep), &rep); | |||
1241 | return Success0; | |||
1242 | } | |||
1243 | ||||
1244 | /* | |||
1245 | * ** Get list of system counters available through the extension | |||
1246 | */ | |||
1247 | static int | |||
1248 | ProcSyncListSystemCounters(ClientPtr client) | |||
1249 | { | |||
1250 | xSyncListSystemCountersReply rep = { | |||
1251 | .type = X_Reply1, | |||
1252 | .sequenceNumber = client->sequence, | |||
1253 | .nCounters = 0, | |||
1254 | }; | |||
1255 | SysCounterInfo *psci; | |||
1256 | int len = 0; | |||
1257 | xSyncSystemCounter *list = NULL((void*)0), *walklist = NULL((void*)0); | |||
| ||||
1258 | ||||
1259 | REQUEST_SIZE_MATCH(xSyncListSystemCountersReq)if ((sizeof(xSyncListSystemCountersReq) >> 2) != client ->req_len) return(16); | |||
1260 | ||||
1261 | xorg_list_for_each_entry(psci, &SysCounterList, entry)for (psci = ((void*)0), psci = (typeof(*psci) *)((char *)((& SysCounterList)->next) - __builtin_offsetof(typeof(*psci), entry)); &psci->entry != (&SysCounterList); psci = (typeof(*psci) *)((char *)(psci->entry.next) - __builtin_offsetof (typeof(*psci), entry))) { | |||
1262 | /* pad to 4 byte boundary */ | |||
1263 | len += pad_to_int32(sz_xSyncSystemCounter14 + strlen(psci->name)); | |||
1264 | ++rep.nCounters; | |||
1265 | } | |||
1266 | ||||
1267 | if (len) { | |||
1268 | walklist = list = malloc(len); | |||
1269 | if (!list) | |||
1270 | return BadAlloc11; | |||
1271 | } | |||
1272 | ||||
1273 | rep.length = bytes_to_int32(len); | |||
1274 | ||||
1275 | if (client->swapped) { | |||
1276 | swaps(&rep.sequenceNumber)do { if (sizeof(*(&rep.sequenceNumber)) != 2) wrong_size( ); if (__builtin_constant_p((uintptr_t)(&rep.sequenceNumber ) & 1) && ((uintptr_t)(&rep.sequenceNumber) & 1) == 0) *(&rep.sequenceNumber) = lswaps(*(&rep.sequenceNumber )); else swap_uint16((uint16_t *)(&rep.sequenceNumber)); } while (0); | |||
1277 | swapl(&rep.length)do { if (sizeof(*(&rep.length)) != 4) wrong_size(); if (__builtin_constant_p ((uintptr_t)(&rep.length) & 3) && ((uintptr_t )(&rep.length) & 3) == 0) *(&rep.length) = lswapl (*(&rep.length)); else swap_uint32((uint32_t *)(&rep. length)); } while (0); | |||
1278 | swapl(&rep.nCounters)do { if (sizeof(*(&rep.nCounters)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&rep.nCounters) & 3 ) && ((uintptr_t)(&rep.nCounters) & 3) == 0) * (&rep.nCounters) = lswapl(*(&rep.nCounters)); else swap_uint32 ((uint32_t *)(&rep.nCounters)); } while (0); | |||
1279 | } | |||
1280 | ||||
1281 | xorg_list_for_each_entry(psci, &SysCounterList, entry)for (psci = ((void*)0), psci = (typeof(*psci) *)((char *)((& SysCounterList)->next) - __builtin_offsetof(typeof(*psci), entry)); &psci->entry != (&SysCounterList); psci = (typeof(*psci) *)((char *)(psci->entry.next) - __builtin_offsetof (typeof(*psci), entry))) { | |||
1282 | int namelen; | |||
1283 | char *pname_in_reply; | |||
1284 | ||||
1285 | walklist->counter = psci->pCounter->sync.id; | |||
| ||||
1286 | walklist->resolution_hi = XSyncValueHigh32(psci->resolution)((psci->resolution).hi); | |||
1287 | walklist->resolution_lo = XSyncValueLow32(psci->resolution)((psci->resolution).lo); | |||
1288 | namelen = strlen(psci->name); | |||
1289 | walklist->name_length = namelen; | |||
1290 | ||||
1291 | if (client->swapped) { | |||
1292 | swapl(&walklist->counter)do { if (sizeof(*(&walklist->counter)) != 4) wrong_size (); if (__builtin_constant_p((uintptr_t)(&walklist->counter ) & 3) && ((uintptr_t)(&walklist->counter) & 3) == 0) *(&walklist->counter) = lswapl(*(& walklist->counter)); else swap_uint32((uint32_t *)(&walklist ->counter)); } while (0); | |||
1293 | swapl(&walklist->resolution_hi)do { if (sizeof(*(&walklist->resolution_hi)) != 4) wrong_size (); if (__builtin_constant_p((uintptr_t)(&walklist->resolution_hi ) & 3) && ((uintptr_t)(&walklist->resolution_hi ) & 3) == 0) *(&walklist->resolution_hi) = lswapl( *(&walklist->resolution_hi)); else swap_uint32((uint32_t *)(&walklist->resolution_hi)); } while (0); | |||
1294 | swapl(&walklist->resolution_lo)do { if (sizeof(*(&walklist->resolution_lo)) != 4) wrong_size (); if (__builtin_constant_p((uintptr_t)(&walklist->resolution_lo ) & 3) && ((uintptr_t)(&walklist->resolution_lo ) & 3) == 0) *(&walklist->resolution_lo) = lswapl( *(&walklist->resolution_lo)); else swap_uint32((uint32_t *)(&walklist->resolution_lo)); } while (0); | |||
1295 | swaps(&walklist->name_length)do { if (sizeof(*(&walklist->name_length)) != 2) wrong_size (); if (__builtin_constant_p((uintptr_t)(&walklist->name_length ) & 1) && ((uintptr_t)(&walklist->name_length ) & 1) == 0) *(&walklist->name_length) = lswaps(*( &walklist->name_length)); else swap_uint16((uint16_t * )(&walklist->name_length)); } while (0); | |||
1296 | } | |||
1297 | ||||
1298 | pname_in_reply = ((char *) walklist) + sz_xSyncSystemCounter14; | |||
1299 | strncpy(pname_in_reply, psci->name, namelen)__builtin___strncpy_chk (pname_in_reply, psci->name, namelen , __builtin_object_size (pname_in_reply, 2 > 1 ? 1 : 0)); | |||
1300 | walklist = (xSyncSystemCounter *) (((char *) walklist) + | |||
1301 | pad_to_int32(sz_xSyncSystemCounter14 + | |||
1302 | namelen)); | |||
1303 | } | |||
1304 | ||||
1305 | WriteToClient(client, sizeof(rep), &rep); | |||
1306 | if (len) { | |||
1307 | WriteToClient(client, len, list); | |||
1308 | free(list); | |||
1309 | } | |||
1310 | ||||
1311 | return Success0; | |||
1312 | } | |||
1313 | ||||
1314 | /* | |||
1315 | * ** Set client Priority | |||
1316 | */ | |||
1317 | static int | |||
1318 | ProcSyncSetPriority(ClientPtr client) | |||
1319 | { | |||
1320 | REQUEST(xSyncSetPriorityReq)xSyncSetPriorityReq *stuff = (xSyncSetPriorityReq *)client-> requestBuffer; | |||
1321 | ClientPtr priorityclient; | |||
1322 | int rc; | |||
1323 | ||||
1324 | REQUEST_SIZE_MATCH(xSyncSetPriorityReq)if ((sizeof(xSyncSetPriorityReq) >> 2) != client->req_len ) return(16); | |||
1325 | ||||
1326 | if (stuff->id == None0L) | |||
1327 | priorityclient = client; | |||
1328 | else { | |||
1329 | rc = dixLookupClient(&priorityclient, stuff->id, client, | |||
1330 | DixSetAttrAccess(1<<5)); | |||
1331 | if (rc != Success0) | |||
1332 | return rc; | |||
1333 | } | |||
1334 | ||||
1335 | if (priorityclient->priority != stuff->priority) { | |||
1336 | priorityclient->priority = stuff->priority; | |||
1337 | ||||
1338 | /* The following will force the server back into WaitForSomething | |||
1339 | * so that the change in this client's priority is immediately | |||
1340 | * reflected. | |||
1341 | */ | |||
1342 | isItTimeToYield = TRUE1; | |||
1343 | dispatchException |= DE_PRIORITYCHANGE4; | |||
1344 | } | |||
1345 | return Success0; | |||
1346 | } | |||
1347 | ||||
1348 | /* | |||
1349 | * ** Get client Priority | |||
1350 | */ | |||
1351 | static int | |||
1352 | ProcSyncGetPriority(ClientPtr client) | |||
1353 | { | |||
1354 | REQUEST(xSyncGetPriorityReq)xSyncGetPriorityReq *stuff = (xSyncGetPriorityReq *)client-> requestBuffer; | |||
1355 | xSyncGetPriorityReply rep; | |||
1356 | ClientPtr priorityclient; | |||
1357 | int rc; | |||
1358 | ||||
1359 | REQUEST_SIZE_MATCH(xSyncGetPriorityReq)if ((sizeof(xSyncGetPriorityReq) >> 2) != client->req_len ) return(16); | |||
1360 | ||||
1361 | if (stuff->id == None0L) | |||
1362 | priorityclient = client; | |||
1363 | else { | |||
1364 | rc = dixLookupClient(&priorityclient, stuff->id, client, | |||
1365 | DixGetAttrAccess(1<<4)); | |||
1366 | if (rc != Success0) | |||
1367 | return rc; | |||
1368 | } | |||
1369 | ||||
1370 | rep = (xSyncGetPriorityReply) { | |||
1371 | .type = X_Reply1, | |||
1372 | .sequenceNumber = client->sequence, | |||
1373 | .length = 0, | |||
1374 | .priority = priorityclient->priority | |||
1375 | }; | |||
1376 | ||||
1377 | if (client->swapped) { | |||
1378 | swaps(&rep.sequenceNumber)do { if (sizeof(*(&rep.sequenceNumber)) != 2) wrong_size( ); if (__builtin_constant_p((uintptr_t)(&rep.sequenceNumber ) & 1) && ((uintptr_t)(&rep.sequenceNumber) & 1) == 0) *(&rep.sequenceNumber) = lswaps(*(&rep.sequenceNumber )); else swap_uint16((uint16_t *)(&rep.sequenceNumber)); } while (0); | |||
1379 | swapl(&rep.priority)do { if (sizeof(*(&rep.priority)) != 4) wrong_size(); if ( __builtin_constant_p((uintptr_t)(&rep.priority) & 3) && ((uintptr_t)(&rep.priority) & 3) == 0) *(&rep.priority ) = lswapl(*(&rep.priority)); else swap_uint32((uint32_t * )(&rep.priority)); } while (0); | |||
1380 | } | |||
1381 | ||||
1382 | WriteToClient(client, sizeof(xSyncGetPriorityReply), &rep); | |||
1383 | ||||
1384 | return Success0; | |||
1385 | } | |||
1386 | ||||
1387 | /* | |||
1388 | * ** Create a new counter | |||
1389 | */ | |||
1390 | static int | |||
1391 | ProcSyncCreateCounter(ClientPtr client) | |||
1392 | { | |||
1393 | REQUEST(xSyncCreateCounterReq)xSyncCreateCounterReq *stuff = (xSyncCreateCounterReq *)client ->requestBuffer; | |||
1394 | CARD64XSyncValue initial; | |||
1395 | ||||
1396 | REQUEST_SIZE_MATCH(xSyncCreateCounterReq)if ((sizeof(xSyncCreateCounterReq) >> 2) != client-> req_len) return(16); | |||
1397 | ||||
1398 | LEGAL_NEW_RESOURCE(stuff->cid, client)if (!LegalNewID(stuff->cid,client)) { client->errorValue = stuff->cid; return 14; }; | |||
1399 | ||||
1400 | XSyncIntsToValue(&initial, stuff->initial_value_lo,((&initial)->lo = (stuff->initial_value_lo), (& initial)->hi = (stuff->initial_value_hi)) | |||
1401 | stuff->initial_value_hi)((&initial)->lo = (stuff->initial_value_lo), (& initial)->hi = (stuff->initial_value_hi)); | |||
1402 | if (!SyncCreateCounter(client, stuff->cid, initial)) | |||
1403 | return BadAlloc11; | |||
1404 | ||||
1405 | return Success0; | |||
1406 | } | |||
1407 | ||||
1408 | /* | |||
1409 | * ** Set Counter value | |||
1410 | */ | |||
1411 | static int | |||
1412 | ProcSyncSetCounter(ClientPtr client) | |||
1413 | { | |||
1414 | REQUEST(xSyncSetCounterReq)xSyncSetCounterReq *stuff = (xSyncSetCounterReq *)client-> requestBuffer; | |||
1415 | SyncCounter *pCounter; | |||
1416 | CARD64XSyncValue newvalue; | |||
1417 | int rc; | |||
1418 | ||||
1419 | REQUEST_SIZE_MATCH(xSyncSetCounterReq)if ((sizeof(xSyncSetCounterReq) >> 2) != client->req_len ) return(16); | |||
1420 | ||||
1421 | rc = dixLookupResourceByType((void **) &pCounter, stuff->cid, RTCounter, | |||
1422 | client, DixWriteAccess(1<<1)); | |||
1423 | if (rc != Success0) | |||
1424 | return rc; | |||
1425 | ||||
1426 | if (IsSystemCounter(pCounter)(pCounter && (pCounter->sync.client == ((void*)0)) )) { | |||
1427 | client->errorValue = stuff->cid; | |||
1428 | return BadAccess10; | |||
1429 | } | |||
1430 | ||||
1431 | XSyncIntsToValue(&newvalue, stuff->value_lo, stuff->value_hi)((&newvalue)->lo = (stuff->value_lo), (&newvalue )->hi = (stuff->value_hi)); | |||
1432 | SyncChangeCounter(pCounter, newvalue); | |||
1433 | return Success0; | |||
1434 | } | |||
1435 | ||||
1436 | /* | |||
1437 | * ** Change Counter value | |||
1438 | */ | |||
1439 | static int | |||
1440 | ProcSyncChangeCounter(ClientPtr client) | |||
1441 | { | |||
1442 | REQUEST(xSyncChangeCounterReq)xSyncChangeCounterReq *stuff = (xSyncChangeCounterReq *)client ->requestBuffer; | |||
1443 | SyncCounter *pCounter; | |||
1444 | CARD64XSyncValue newvalue; | |||
1445 | Bool overflow; | |||
1446 | int rc; | |||
1447 | ||||
1448 | REQUEST_SIZE_MATCH(xSyncChangeCounterReq)if ((sizeof(xSyncChangeCounterReq) >> 2) != client-> req_len) return(16); | |||
1449 | ||||
1450 | rc = dixLookupResourceByType((void **) &pCounter, stuff->cid, RTCounter, | |||
1451 | client, DixWriteAccess(1<<1)); | |||
1452 | if (rc != Success0) | |||
1453 | return rc; | |||
1454 | ||||
1455 | if (IsSystemCounter(pCounter)(pCounter && (pCounter->sync.client == ((void*)0)) )) { | |||
1456 | client->errorValue = stuff->cid; | |||
1457 | return BadAccess10; | |||
1458 | } | |||
1459 | ||||
1460 | XSyncIntsToValue(&newvalue, stuff->value_lo, stuff->value_hi)((&newvalue)->lo = (stuff->value_lo), (&newvalue )->hi = (stuff->value_hi)); | |||
1461 | XSyncValueAdd(&newvalue, pCounter->value, newvalue, &overflow){ int t = (pCounter->value).lo; Bool signa = (((pCounter-> value).hi & 0x80000000) ? 1 : 0); Bool signb = (((newvalue ).hi & 0x80000000) ? 1 : 0); ((&newvalue)->lo = (pCounter ->value).lo + (newvalue).lo); ((&newvalue)->hi = (pCounter ->value).hi + (newvalue).hi); if (t>(&newvalue)-> lo) (&newvalue)->hi++; *&overflow = ((signa == signb ) && !(signa == (((*&newvalue).hi & 0x80000000 ) ? 1 : 0))); }; | |||
1462 | if (overflow) { | |||
1463 | /* XXX 64 bit value can't fit in 32 bits; do the best we can */ | |||
1464 | client->errorValue = stuff->value_hi; | |||
1465 | return BadValue2; | |||
1466 | } | |||
1467 | SyncChangeCounter(pCounter, newvalue); | |||
1468 | return Success0; | |||
1469 | } | |||
1470 | ||||
1471 | /* | |||
1472 | * ** Destroy a counter | |||
1473 | */ | |||
1474 | static int | |||
1475 | ProcSyncDestroyCounter(ClientPtr client) | |||
1476 | { | |||
1477 | REQUEST(xSyncDestroyCounterReq)xSyncDestroyCounterReq *stuff = (xSyncDestroyCounterReq *)client ->requestBuffer; | |||
1478 | SyncCounter *pCounter; | |||
1479 | int rc; | |||
1480 | ||||
1481 | REQUEST_SIZE_MATCH(xSyncDestroyCounterReq)if ((sizeof(xSyncDestroyCounterReq) >> 2) != client-> req_len) return(16); | |||
1482 | ||||
1483 | rc = dixLookupResourceByType((void **) &pCounter, stuff->counter, | |||
1484 | RTCounter, client, DixDestroyAccess(1<<2)); | |||
1485 | if (rc != Success0) | |||
1486 | return rc; | |||
1487 | ||||
1488 | if (IsSystemCounter(pCounter)(pCounter && (pCounter->sync.client == ((void*)0)) )) { | |||
1489 | client->errorValue = stuff->counter; | |||
1490 | return BadAccess10; | |||
1491 | } | |||
1492 | FreeResource(pCounter->sync.id, RT_NONE((RESTYPE)0)); | |||
1493 | return Success0; | |||
1494 | } | |||
1495 | ||||
1496 | static SyncAwaitUnion * | |||
1497 | SyncAwaitPrologue(ClientPtr client, int items) | |||
1498 | { | |||
1499 | SyncAwaitUnion *pAwaitUnion; | |||
1500 | ||||
1501 | /* all the memory for the entire await list is allocated | |||
1502 | * here in one chunk | |||
1503 | */ | |||
1504 | pAwaitUnion = xallocarray(items + 1, sizeof(SyncAwaitUnion))xreallocarray(((void*)0), (items + 1), (sizeof(SyncAwaitUnion ))); | |||
1505 | if (!pAwaitUnion) | |||
1506 | return NULL((void*)0); | |||
1507 | ||||
1508 | /* first item is the header, remainder are real wait conditions */ | |||
1509 | ||||
1510 | pAwaitUnion->header.delete_id = FakeClientID(client->index); | |||
1511 | pAwaitUnion->header.client = client; | |||
1512 | pAwaitUnion->header.num_waitconditions = 0; | |||
1513 | ||||
1514 | if (!AddResourceDarwin_X_AddResource(pAwaitUnion->header.delete_id, RTAwait, pAwaitUnion)) | |||
1515 | return NULL((void*)0); | |||
1516 | ||||
1517 | return pAwaitUnion; | |||
1518 | } | |||
1519 | ||||
1520 | static void | |||
1521 | SyncAwaitEpilogue(ClientPtr client, int items, SyncAwaitUnion * pAwaitUnion) | |||
1522 | { | |||
1523 | SyncAwait *pAwait; | |||
1524 | int i; | |||
1525 | ||||
1526 | IgnoreClient(client); | |||
1527 | ||||
1528 | /* see if any of the triggers are already true */ | |||
1529 | ||||
1530 | pAwait = &(pAwaitUnion + 1)->await; /* skip over header */ | |||
1531 | for (i = 0; i < items; i++, pAwait++) { | |||
1532 | CARD64XSyncValue value; | |||
1533 | ||||
1534 | /* don't have to worry about NULL counters because the request | |||
1535 | * errors before we get here out if they occur | |||
1536 | */ | |||
1537 | switch (pAwait->trigger.pSync->type) { | |||
1538 | case SYNC_COUNTER0: | |||
1539 | value = ((SyncCounter *) pAwait->trigger.pSync)->value; | |||
1540 | break; | |||
1541 | default: | |||
1542 | XSyncIntToValue(&value, 0)((&value)->hi=((0<0)?~0:0),(&value)->lo=(0)); | |||
1543 | } | |||
1544 | ||||
1545 | if ((*pAwait->trigger.CheckTrigger) (&pAwait->trigger, value)) { | |||
1546 | (*pAwait->trigger.TriggerFired) (&pAwait->trigger); | |||
1547 | break; /* once is enough */ | |||
1548 | } | |||
1549 | } | |||
1550 | } | |||
1551 | ||||
1552 | /* | |||
1553 | * ** Await | |||
1554 | */ | |||
1555 | static int | |||
1556 | ProcSyncAwait(ClientPtr client) | |||
1557 | { | |||
1558 | REQUEST(xSyncAwaitReq)xSyncAwaitReq *stuff = (xSyncAwaitReq *)client->requestBuffer; | |||
1559 | int len, items; | |||
1560 | int i; | |||
1561 | xSyncWaitCondition *pProtocolWaitConds; | |||
1562 | SyncAwaitUnion *pAwaitUnion; | |||
1563 | SyncAwait *pAwait; | |||
1564 | int status; | |||
1565 | ||||
1566 | REQUEST_AT_LEAST_SIZE(xSyncAwaitReq)if ((sizeof(xSyncAwaitReq) >> 2) > client->req_len ) return(16); | |||
1567 | ||||
1568 | len = client->req_len << 2; | |||
1569 | len -= sz_xSyncAwaitReq4; | |||
1570 | items = len / sz_xSyncWaitCondition28; | |||
1571 | ||||
1572 | if (items * sz_xSyncWaitCondition28 != len) { | |||
1573 | return BadLength16; | |||
1574 | } | |||
1575 | if (items == 0) { | |||
1576 | client->errorValue = items; /* XXX protocol change */ | |||
1577 | return BadValue2; | |||
1578 | } | |||
1579 | ||||
1580 | if (!(pAwaitUnion = SyncAwaitPrologue(client, items))) | |||
1581 | return BadAlloc11; | |||
1582 | ||||
1583 | /* don't need to do any more memory allocation for this request! */ | |||
1584 | ||||
1585 | pProtocolWaitConds = (xSyncWaitCondition *) &stuff[1]; | |||
1586 | ||||
1587 | pAwait = &(pAwaitUnion + 1)->await; /* skip over header */ | |||
1588 | for (i = 0; i < items; i++, pProtocolWaitConds++, pAwait++) { | |||
1589 | if (pProtocolWaitConds->counter == None0L) { /* XXX protocol change */ | |||
1590 | /* this should take care of removing any triggers created by | |||
1591 | * this request that have already been registered on sync objects | |||
1592 | */ | |||
1593 | FreeResource(pAwaitUnion->header.delete_id, RT_NONE((RESTYPE)0)); | |||
1594 | client->errorValue = pProtocolWaitConds->counter; | |||
1595 | return SyncErrorBase + XSyncBadCounter0L; | |||
1596 | } | |||
1597 | ||||
1598 | /* sanity checks are in SyncInitTrigger */ | |||
1599 | pAwait->trigger.pSync = NULL((void*)0); | |||
1600 | pAwait->trigger.value_type = pProtocolWaitConds->value_type; | |||
1601 | XSyncIntsToValue(&pAwait->trigger.wait_value,((&pAwait->trigger.wait_value)->lo = (pProtocolWaitConds ->wait_value_lo), (&pAwait->trigger.wait_value)-> hi = (pProtocolWaitConds->wait_value_hi)) | |||
1602 | pProtocolWaitConds->wait_value_lo,((&pAwait->trigger.wait_value)->lo = (pProtocolWaitConds ->wait_value_lo), (&pAwait->trigger.wait_value)-> hi = (pProtocolWaitConds->wait_value_hi)) | |||
1603 | pProtocolWaitConds->wait_value_hi)((&pAwait->trigger.wait_value)->lo = (pProtocolWaitConds ->wait_value_lo), (&pAwait->trigger.wait_value)-> hi = (pProtocolWaitConds->wait_value_hi)); | |||
1604 | pAwait->trigger.test_type = pProtocolWaitConds->test_type; | |||
1605 | ||||
1606 | status = SyncInitTrigger(client, &pAwait->trigger, | |||
1607 | pProtocolWaitConds->counter, RTCounter, | |||
1608 | XSyncCAAllTrigger((1L<<0) | (1L<<1) | (1L<<2) | (1L<<3 ))); | |||
1609 | if (status != Success0) { | |||
1610 | /* this should take care of removing any triggers created by | |||
1611 | * this request that have already been registered on sync objects | |||
1612 | */ | |||
1613 | FreeResource(pAwaitUnion->header.delete_id, RT_NONE((RESTYPE)0)); | |||
1614 | return status; | |||
1615 | } | |||
1616 | /* this is not a mistake -- same function works for both cases */ | |||
1617 | pAwait->trigger.TriggerFired = SyncAwaitTriggerFired; | |||
1618 | pAwait->trigger.CounterDestroyed = SyncAwaitTriggerFired; | |||
1619 | XSyncIntsToValue(&pAwait->event_threshold,((&pAwait->event_threshold)->lo = (pProtocolWaitConds ->event_threshold_lo), (&pAwait->event_threshold)-> hi = (pProtocolWaitConds->event_threshold_hi)) | |||
1620 | pProtocolWaitConds->event_threshold_lo,((&pAwait->event_threshold)->lo = (pProtocolWaitConds ->event_threshold_lo), (&pAwait->event_threshold)-> hi = (pProtocolWaitConds->event_threshold_hi)) | |||
1621 | pProtocolWaitConds->event_threshold_hi)((&pAwait->event_threshold)->lo = (pProtocolWaitConds ->event_threshold_lo), (&pAwait->event_threshold)-> hi = (pProtocolWaitConds->event_threshold_hi)); | |||
1622 | pAwait->pHeader = &pAwaitUnion->header; | |||
1623 | pAwaitUnion->header.num_waitconditions++; | |||
1624 | } | |||
1625 | ||||
1626 | SyncAwaitEpilogue(client, items, pAwaitUnion); | |||
1627 | ||||
1628 | return Success0; | |||
1629 | } | |||
1630 | ||||
1631 | /* | |||
1632 | * ** Query a counter | |||
1633 | */ | |||
1634 | static int | |||
1635 | ProcSyncQueryCounter(ClientPtr client) | |||
1636 | { | |||
1637 | REQUEST(xSyncQueryCounterReq)xSyncQueryCounterReq *stuff = (xSyncQueryCounterReq *)client-> requestBuffer; | |||
1638 | xSyncQueryCounterReply rep; | |||
1639 | SyncCounter *pCounter; | |||
1640 | int rc; | |||
1641 | ||||
1642 | REQUEST_SIZE_MATCH(xSyncQueryCounterReq)if ((sizeof(xSyncQueryCounterReq) >> 2) != client->req_len ) return(16); | |||
1643 | ||||
1644 | rc = dixLookupResourceByType((void **) &pCounter, stuff->counter, | |||
1645 | RTCounter, client, DixReadAccess(1<<0)); | |||
1646 | if (rc != Success0) | |||
1647 | return rc; | |||
1648 | ||||
1649 | /* if system counter, ask it what the current value is */ | |||
1650 | if (IsSystemCounter(pCounter)(pCounter && (pCounter->sync.client == ((void*)0)) )) { | |||
1651 | (*pCounter->pSysCounterInfo->QueryValue) ((void *) pCounter, | |||
1652 | &pCounter->value); | |||
1653 | } | |||
1654 | ||||
1655 | rep = (xSyncQueryCounterReply) { | |||
1656 | .type = X_Reply1, | |||
1657 | .sequenceNumber = client->sequence, | |||
1658 | .length = 0, | |||
1659 | .value_hi = XSyncValueHigh32(pCounter->value)((pCounter->value).hi), | |||
1660 | .value_lo = XSyncValueLow32(pCounter->value)((pCounter->value).lo) | |||
1661 | }; | |||
1662 | ||||
1663 | if (client->swapped) { | |||
1664 | swaps(&rep.sequenceNumber)do { if (sizeof(*(&rep.sequenceNumber)) != 2) wrong_size( ); if (__builtin_constant_p((uintptr_t)(&rep.sequenceNumber ) & 1) && ((uintptr_t)(&rep.sequenceNumber) & 1) == 0) *(&rep.sequenceNumber) = lswaps(*(&rep.sequenceNumber )); else swap_uint16((uint16_t *)(&rep.sequenceNumber)); } while (0); | |||
1665 | swapl(&rep.length)do { if (sizeof(*(&rep.length)) != 4) wrong_size(); if (__builtin_constant_p ((uintptr_t)(&rep.length) & 3) && ((uintptr_t )(&rep.length) & 3) == 0) *(&rep.length) = lswapl (*(&rep.length)); else swap_uint32((uint32_t *)(&rep. length)); } while (0); | |||
1666 | swapl(&rep.value_hi)do { if (sizeof(*(&rep.value_hi)) != 4) wrong_size(); if ( __builtin_constant_p((uintptr_t)(&rep.value_hi) & 3) && ((uintptr_t)(&rep.value_hi) & 3) == 0) *(&rep.value_hi ) = lswapl(*(&rep.value_hi)); else swap_uint32((uint32_t * )(&rep.value_hi)); } while (0); | |||
1667 | swapl(&rep.value_lo)do { if (sizeof(*(&rep.value_lo)) != 4) wrong_size(); if ( __builtin_constant_p((uintptr_t)(&rep.value_lo) & 3) && ((uintptr_t)(&rep.value_lo) & 3) == 0) *(&rep.value_lo ) = lswapl(*(&rep.value_lo)); else swap_uint32((uint32_t * )(&rep.value_lo)); } while (0); | |||
1668 | } | |||
1669 | WriteToClient(client, sizeof(xSyncQueryCounterReply), &rep); | |||
1670 | return Success0; | |||
1671 | } | |||
1672 | ||||
1673 | /* | |||
1674 | * ** Create Alarm | |||
1675 | */ | |||
1676 | static int | |||
1677 | ProcSyncCreateAlarm(ClientPtr client) | |||
1678 | { | |||
1679 | REQUEST(xSyncCreateAlarmReq)xSyncCreateAlarmReq *stuff = (xSyncCreateAlarmReq *)client-> requestBuffer; | |||
1680 | SyncAlarm *pAlarm; | |||
1681 | int status; | |||
1682 | unsigned long len, vmask; | |||
1683 | SyncTrigger *pTrigger; | |||
1684 | ||||
1685 | REQUEST_AT_LEAST_SIZE(xSyncCreateAlarmReq)if ((sizeof(xSyncCreateAlarmReq) >> 2) > client-> req_len ) return(16); | |||
1686 | ||||
1687 | LEGAL_NEW_RESOURCE(stuff->id, client)if (!LegalNewID(stuff->id,client)) { client->errorValue = stuff->id; return 14; }; | |||
1688 | ||||
1689 | vmask = stuff->valueMask; | |||
1690 | len = client->req_len - bytes_to_int32(sizeof(xSyncCreateAlarmReq)); | |||
1691 | /* the "extra" call to Ones accounts for the presence of 64 bit values */ | |||
1692 | if (len != (Ones(vmask) + Ones(vmask & (XSyncCAValue(1L<<2) | XSyncCADelta(1L<<4))))) | |||
1693 | return BadLength16; | |||
1694 | ||||
1695 | if (!(pAlarm = malloc(sizeof(SyncAlarm)))) { | |||
1696 | return BadAlloc11; | |||
1697 | } | |||
1698 | ||||
1699 | /* set up defaults */ | |||
1700 | ||||
1701 | pTrigger = &pAlarm->trigger; | |||
1702 | pTrigger->pSync = NULL((void*)0); | |||
1703 | pTrigger->value_type = XSyncAbsolute; | |||
1704 | XSyncIntToValue(&pTrigger->wait_value, 0L)((&pTrigger->wait_value)->hi=((0L<0)?~0:0),(& pTrigger->wait_value)->lo=(0L)); | |||
1705 | pTrigger->test_type = XSyncPositiveComparison; | |||
1706 | pTrigger->TriggerFired = SyncAlarmTriggerFired; | |||
1707 | pTrigger->CounterDestroyed = SyncAlarmCounterDestroyed; | |||
1708 | status = SyncInitTrigger(client, pTrigger, None0L, RTCounter, | |||
1709 | XSyncCAAllTrigger((1L<<0) | (1L<<1) | (1L<<2) | (1L<<3 ))); | |||
1710 | if (status != Success0) { | |||
1711 | free(pAlarm); | |||
1712 | return status; | |||
1713 | } | |||
1714 | ||||
1715 | pAlarm->client = client; | |||
1716 | pAlarm->alarm_id = stuff->id; | |||
1717 | XSyncIntToValue(&pAlarm->delta, 1L)((&pAlarm->delta)->hi=((1L<0)?~0:0),(&pAlarm ->delta)->lo=(1L)); | |||
1718 | pAlarm->events = TRUE1; | |||
1719 | pAlarm->state = XSyncAlarmInactive; | |||
1720 | pAlarm->pEventClients = NULL((void*)0); | |||
1721 | status = SyncChangeAlarmAttributes(client, pAlarm, vmask, | |||
1722 | (CARD32 *) &stuff[1]); | |||
1723 | if (status != Success0) { | |||
1724 | free(pAlarm); | |||
1725 | return status; | |||
1726 | } | |||
1727 | ||||
1728 | if (!AddResourceDarwin_X_AddResource(stuff->id, RTAlarm, pAlarm)) | |||
1729 | return BadAlloc11; | |||
1730 | ||||
1731 | /* see if alarm already triggered. NULL counter will not trigger | |||
1732 | * in CreateAlarm and sets alarm state to Inactive. | |||
1733 | */ | |||
1734 | ||||
1735 | if (!pTrigger->pSync) { | |||
1736 | pAlarm->state = XSyncAlarmInactive; /* XXX protocol change */ | |||
1737 | } | |||
1738 | else { | |||
1739 | SyncCounter *pCounter; | |||
1740 | ||||
1741 | if (!SyncCheckWarnIsCounter(pTrigger->pSync, | |||
1742 | WARN_INVALID_COUNTER_ALARM)) { | |||
1743 | FreeResource(stuff->id, RT_NONE((RESTYPE)0)); | |||
1744 | return BadAlloc11; | |||
1745 | } | |||
1746 | ||||
1747 | pCounter = (SyncCounter *) pTrigger->pSync; | |||
1748 | ||||
1749 | if ((*pTrigger->CheckTrigger) (pTrigger, pCounter->value)) | |||
1750 | (*pTrigger->TriggerFired) (pTrigger); | |||
1751 | } | |||
1752 | ||||
1753 | return Success0; | |||
1754 | } | |||
1755 | ||||
1756 | /* | |||
1757 | * ** Change Alarm | |||
1758 | */ | |||
1759 | static int | |||
1760 | ProcSyncChangeAlarm(ClientPtr client) | |||
1761 | { | |||
1762 | REQUEST(xSyncChangeAlarmReq)xSyncChangeAlarmReq *stuff = (xSyncChangeAlarmReq *)client-> requestBuffer; | |||
1763 | SyncAlarm *pAlarm; | |||
1764 | SyncCounter *pCounter = NULL((void*)0); | |||
1765 | long vmask; | |||
1766 | int len, status; | |||
1767 | ||||
1768 | REQUEST_AT_LEAST_SIZE(xSyncChangeAlarmReq)if ((sizeof(xSyncChangeAlarmReq) >> 2) > client-> req_len ) return(16); | |||
1769 | ||||
1770 | status = dixLookupResourceByType((void **) &pAlarm, stuff->alarm, RTAlarm, | |||
1771 | client, DixWriteAccess(1<<1)); | |||
1772 | if (status != Success0) | |||
1773 | return status; | |||
1774 | ||||
1775 | vmask = stuff->valueMask; | |||
1776 | len = client->req_len - bytes_to_int32(sizeof(xSyncChangeAlarmReq)); | |||
1777 | /* the "extra" call to Ones accounts for the presence of 64 bit values */ | |||
1778 | if (len != (Ones(vmask) + Ones(vmask & (XSyncCAValue(1L<<2) | XSyncCADelta(1L<<4))))) | |||
1779 | return BadLength16; | |||
1780 | ||||
1781 | if ((status = SyncChangeAlarmAttributes(client, pAlarm, vmask, | |||
1782 | (CARD32 *) &stuff[1])) != Success0) | |||
1783 | return status; | |||
1784 | ||||
1785 | if (SyncCheckWarnIsCounter(pAlarm->trigger.pSync, | |||
1786 | WARN_INVALID_COUNTER_ALARM)) | |||
1787 | pCounter = (SyncCounter *) pAlarm->trigger.pSync; | |||
1788 | ||||
1789 | /* see if alarm already triggered. NULL counter WILL trigger | |||
1790 | * in ChangeAlarm. | |||
1791 | */ | |||
1792 | ||||
1793 | if (!pCounter || | |||
1794 | (*pAlarm->trigger.CheckTrigger) (&pAlarm->trigger, pCounter->value)) { | |||
1795 | (*pAlarm->trigger.TriggerFired) (&pAlarm->trigger); | |||
1796 | } | |||
1797 | return Success0; | |||
1798 | } | |||
1799 | ||||
1800 | static int | |||
1801 | ProcSyncQueryAlarm(ClientPtr client) | |||
1802 | { | |||
1803 | REQUEST(xSyncQueryAlarmReq)xSyncQueryAlarmReq *stuff = (xSyncQueryAlarmReq *)client-> requestBuffer; | |||
1804 | SyncAlarm *pAlarm; | |||
1805 | xSyncQueryAlarmReply rep; | |||
1806 | SyncTrigger *pTrigger; | |||
1807 | int rc; | |||
1808 | ||||
1809 | REQUEST_SIZE_MATCH(xSyncQueryAlarmReq)if ((sizeof(xSyncQueryAlarmReq) >> 2) != client->req_len ) return(16); | |||
1810 | ||||
1811 | rc = dixLookupResourceByType((void **) &pAlarm, stuff->alarm, RTAlarm, | |||
1812 | client, DixReadAccess(1<<0)); | |||
1813 | if (rc != Success0) | |||
1814 | return rc; | |||
1815 | ||||
1816 | pTrigger = &pAlarm->trigger; | |||
1817 | rep = (xSyncQueryAlarmReply) { | |||
1818 | .type = X_Reply1, | |||
1819 | .sequenceNumber = client->sequence, | |||
1820 | .length = | |||
1821 | bytes_to_int32(sizeof(xSyncQueryAlarmReply) - sizeof(xGenericReply)), | |||
1822 | .counter = (pTrigger->pSync) ? pTrigger->pSync->id : None0L, | |||
1823 | ||||
1824 | #if 0 /* XXX unclear what to do, depends on whether relative value-types | |||
1825 | * are "consumed" immediately and are considered absolute from then | |||
1826 | * on. | |||
1827 | */ | |||
1828 | .value_type = pTrigger->value_type, | |||
1829 | .wait_value_hi = XSyncValueHigh32(pTrigger->wait_value)((pTrigger->wait_value).hi), | |||
1830 | .wait_value_lo = XSyncValueLow32(pTrigger->wait_value)((pTrigger->wait_value).lo), | |||
1831 | #else | |||
1832 | .value_type = XSyncAbsolute, | |||
1833 | .wait_value_hi = XSyncValueHigh32(pTrigger->test_value)((pTrigger->test_value).hi), | |||
1834 | .wait_value_lo = XSyncValueLow32(pTrigger->test_value)((pTrigger->test_value).lo), | |||
1835 | #endif | |||
1836 | ||||
1837 | .test_type = pTrigger->test_type, | |||
1838 | .delta_hi = XSyncValueHigh32(pAlarm->delta)((pAlarm->delta).hi), | |||
1839 | .delta_lo = XSyncValueLow32(pAlarm->delta)((pAlarm->delta).lo), | |||
1840 | .events = pAlarm->events, | |||
1841 | .state = pAlarm->state | |||
1842 | }; | |||
1843 | ||||
1844 | if (client->swapped) { | |||
1845 | swaps(&rep.sequenceNumber)do { if (sizeof(*(&rep.sequenceNumber)) != 2) wrong_size( ); if (__builtin_constant_p((uintptr_t)(&rep.sequenceNumber ) & 1) && ((uintptr_t)(&rep.sequenceNumber) & 1) == 0) *(&rep.sequenceNumber) = lswaps(*(&rep.sequenceNumber )); else swap_uint16((uint16_t *)(&rep.sequenceNumber)); } while (0); | |||
1846 | swapl(&rep.length)do { if (sizeof(*(&rep.length)) != 4) wrong_size(); if (__builtin_constant_p ((uintptr_t)(&rep.length) & 3) && ((uintptr_t )(&rep.length) & 3) == 0) *(&rep.length) = lswapl (*(&rep.length)); else swap_uint32((uint32_t *)(&rep. length)); } while (0); | |||
1847 | swapl(&rep.counter)do { if (sizeof(*(&rep.counter)) != 4) wrong_size(); if ( __builtin_constant_p((uintptr_t)(&rep.counter) & 3) && ((uintptr_t)(&rep.counter) & 3) == 0) *(&rep.counter ) = lswapl(*(&rep.counter)); else swap_uint32((uint32_t * )(&rep.counter)); } while (0); | |||
1848 | swapl(&rep.wait_value_hi)do { if (sizeof(*(&rep.wait_value_hi)) != 4) wrong_size() ; if (__builtin_constant_p((uintptr_t)(&rep.wait_value_hi ) & 3) && ((uintptr_t)(&rep.wait_value_hi) & 3) == 0) *(&rep.wait_value_hi) = lswapl(*(&rep.wait_value_hi )); else swap_uint32((uint32_t *)(&rep.wait_value_hi)); } while (0); | |||
1849 | swapl(&rep.wait_value_lo)do { if (sizeof(*(&rep.wait_value_lo)) != 4) wrong_size() ; if (__builtin_constant_p((uintptr_t)(&rep.wait_value_lo ) & 3) && ((uintptr_t)(&rep.wait_value_lo) & 3) == 0) *(&rep.wait_value_lo) = lswapl(*(&rep.wait_value_lo )); else swap_uint32((uint32_t *)(&rep.wait_value_lo)); } while (0); | |||
1850 | swapl(&rep.test_type)do { if (sizeof(*(&rep.test_type)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&rep.test_type) & 3 ) && ((uintptr_t)(&rep.test_type) & 3) == 0) * (&rep.test_type) = lswapl(*(&rep.test_type)); else swap_uint32 ((uint32_t *)(&rep.test_type)); } while (0); | |||
1851 | swapl(&rep.delta_hi)do { if (sizeof(*(&rep.delta_hi)) != 4) wrong_size(); if ( __builtin_constant_p((uintptr_t)(&rep.delta_hi) & 3) && ((uintptr_t)(&rep.delta_hi) & 3) == 0) *(&rep.delta_hi ) = lswapl(*(&rep.delta_hi)); else swap_uint32((uint32_t * )(&rep.delta_hi)); } while (0); | |||
1852 | swapl(&rep.delta_lo)do { if (sizeof(*(&rep.delta_lo)) != 4) wrong_size(); if ( __builtin_constant_p((uintptr_t)(&rep.delta_lo) & 3) && ((uintptr_t)(&rep.delta_lo) & 3) == 0) *(&rep.delta_lo ) = lswapl(*(&rep.delta_lo)); else swap_uint32((uint32_t * )(&rep.delta_lo)); } while (0); | |||
1853 | } | |||
1854 | ||||
1855 | WriteToClient(client, sizeof(xSyncQueryAlarmReply), &rep); | |||
1856 | return Success0; | |||
1857 | } | |||
1858 | ||||
1859 | static int | |||
1860 | ProcSyncDestroyAlarm(ClientPtr client) | |||
1861 | { | |||
1862 | SyncAlarm *pAlarm; | |||
1863 | int rc; | |||
1864 | ||||
1865 | REQUEST(xSyncDestroyAlarmReq)xSyncDestroyAlarmReq *stuff = (xSyncDestroyAlarmReq *)client-> requestBuffer; | |||
1866 | ||||
1867 | REQUEST_SIZE_MATCH(xSyncDestroyAlarmReq)if ((sizeof(xSyncDestroyAlarmReq) >> 2) != client->req_len ) return(16); | |||
1868 | ||||
1869 | rc = dixLookupResourceByType((void **) &pAlarm, stuff->alarm, RTAlarm, | |||
1870 | client, DixDestroyAccess(1<<2)); | |||
1871 | if (rc != Success0) | |||
1872 | return rc; | |||
1873 | ||||
1874 | FreeResource(stuff->alarm, RT_NONE((RESTYPE)0)); | |||
1875 | return Success0; | |||
1876 | } | |||
1877 | ||||
1878 | static int | |||
1879 | ProcSyncCreateFence(ClientPtr client) | |||
1880 | { | |||
1881 | REQUEST(xSyncCreateFenceReq)xSyncCreateFenceReq *stuff = (xSyncCreateFenceReq *)client-> requestBuffer; | |||
1882 | DrawablePtr pDraw; | |||
1883 | SyncFence *pFence; | |||
1884 | int rc; | |||
1885 | ||||
1886 | REQUEST_SIZE_MATCH(xSyncCreateFenceReq)if ((sizeof(xSyncCreateFenceReq) >> 2) != client->req_len ) return(16); | |||
1887 | ||||
1888 | rc = dixLookupDrawable(&pDraw, stuff->d, client, M_ANY(-1), DixGetAttrAccess(1<<4)); | |||
1889 | if (rc != Success0) | |||
1890 | return rc; | |||
1891 | ||||
1892 | LEGAL_NEW_RESOURCE(stuff->fid, client)if (!LegalNewID(stuff->fid,client)) { client->errorValue = stuff->fid; return 14; }; | |||
1893 | ||||
1894 | if (!(pFence = (SyncFence *) SyncCreate(client, stuff->fid, SYNC_FENCE1))) | |||
1895 | return BadAlloc11; | |||
1896 | ||||
1897 | miSyncInitFence(pDraw->pScreen, pFence, stuff->initially_triggered); | |||
1898 | ||||
1899 | if (!AddResourceDarwin_X_AddResource(stuff->fid, RTFence, (void *) pFence)) | |||
1900 | return BadAlloc11; | |||
1901 | ||||
1902 | return client->noClientException; | |||
1903 | } | |||
1904 | ||||
1905 | static int | |||
1906 | FreeFence(void *obj, XID id) | |||
1907 | { | |||
1908 | SyncFence *pFence = (SyncFence *) obj; | |||
1909 | ||||
1910 | miSyncDestroyFence(pFence); | |||
1911 | ||||
1912 | return Success0; | |||
1913 | } | |||
1914 | ||||
1915 | int | |||
1916 | SyncVerifyFence(SyncFence ** ppSyncFence, XID fid, ClientPtr client, Mask mode) | |||
1917 | { | |||
1918 | int rc = dixLookupResourceByType((void **) ppSyncFence, fid, RTFence, | |||
1919 | client, mode); | |||
1920 | ||||
1921 | if (rc != Success0) | |||
1922 | client->errorValue = fid; | |||
1923 | ||||
1924 | return rc; | |||
1925 | } | |||
1926 | ||||
1927 | static int | |||
1928 | ProcSyncTriggerFence(ClientPtr client) | |||
1929 | { | |||
1930 | REQUEST(xSyncTriggerFenceReq)xSyncTriggerFenceReq *stuff = (xSyncTriggerFenceReq *)client-> requestBuffer; | |||
1931 | SyncFence *pFence; | |||
1932 | int rc; | |||
1933 | ||||
1934 | REQUEST_SIZE_MATCH(xSyncTriggerFenceReq)if ((sizeof(xSyncTriggerFenceReq) >> 2) != client->req_len ) return(16); | |||
1935 | ||||
1936 | rc = dixLookupResourceByType((void **) &pFence, stuff->fid, RTFence, | |||
1937 | client, DixWriteAccess(1<<1)); | |||
1938 | if (rc != Success0) | |||
1939 | return rc; | |||
1940 | ||||
1941 | miSyncTriggerFence(pFence); | |||
1942 | ||||
1943 | return client->noClientException; | |||
1944 | } | |||
1945 | ||||
1946 | static int | |||
1947 | ProcSyncResetFence(ClientPtr client) | |||
1948 | { | |||
1949 | REQUEST(xSyncResetFenceReq)xSyncResetFenceReq *stuff = (xSyncResetFenceReq *)client-> requestBuffer; | |||
1950 | SyncFence *pFence; | |||
1951 | int rc; | |||
1952 | ||||
1953 | REQUEST_SIZE_MATCH(xSyncResetFenceReq)if ((sizeof(xSyncResetFenceReq) >> 2) != client->req_len ) return(16); | |||
1954 | ||||
1955 | rc = dixLookupResourceByType((void **) &pFence, stuff->fid, RTFence, | |||
1956 | client, DixWriteAccess(1<<1)); | |||
1957 | if (rc != Success0) | |||
1958 | return rc; | |||
1959 | ||||
1960 | if (pFence->funcs.CheckTriggered(pFence) != TRUE1) | |||
1961 | return BadMatch8; | |||
1962 | ||||
1963 | pFence->funcs.Reset(pFence); | |||
1964 | ||||
1965 | return client->noClientException; | |||
1966 | } | |||
1967 | ||||
1968 | static int | |||
1969 | ProcSyncDestroyFence(ClientPtr client) | |||
1970 | { | |||
1971 | REQUEST(xSyncDestroyFenceReq)xSyncDestroyFenceReq *stuff = (xSyncDestroyFenceReq *)client-> requestBuffer; | |||
1972 | SyncFence *pFence; | |||
1973 | int rc; | |||
1974 | ||||
1975 | REQUEST_SIZE_MATCH(xSyncDestroyFenceReq)if ((sizeof(xSyncDestroyFenceReq) >> 2) != client->req_len ) return(16); | |||
1976 | ||||
1977 | rc = dixLookupResourceByType((void **) &pFence, stuff->fid, RTFence, | |||
1978 | client, DixDestroyAccess(1<<2)); | |||
1979 | if (rc != Success0) | |||
1980 | return rc; | |||
1981 | ||||
1982 | FreeResource(stuff->fid, RT_NONE((RESTYPE)0)); | |||
1983 | return client->noClientException; | |||
1984 | } | |||
1985 | ||||
1986 | static int | |||
1987 | ProcSyncQueryFence(ClientPtr client) | |||
1988 | { | |||
1989 | REQUEST(xSyncQueryFenceReq)xSyncQueryFenceReq *stuff = (xSyncQueryFenceReq *)client-> requestBuffer; | |||
1990 | xSyncQueryFenceReply rep; | |||
1991 | SyncFence *pFence; | |||
1992 | int rc; | |||
1993 | ||||
1994 | REQUEST_SIZE_MATCH(xSyncQueryFenceReq)if ((sizeof(xSyncQueryFenceReq) >> 2) != client->req_len ) return(16); | |||
1995 | ||||
1996 | rc = dixLookupResourceByType((void **) &pFence, stuff->fid, | |||
1997 | RTFence, client, DixReadAccess(1<<0)); | |||
1998 | if (rc != Success0) | |||
1999 | return rc; | |||
2000 | ||||
2001 | rep = (xSyncQueryFenceReply) { | |||
2002 | .type = X_Reply1, | |||
2003 | .sequenceNumber = client->sequence, | |||
2004 | .length = 0, | |||
2005 | ||||
2006 | .triggered = pFence->funcs.CheckTriggered(pFence) | |||
2007 | }; | |||
2008 | ||||
2009 | if (client->swapped) { | |||
2010 | swaps(&rep.sequenceNumber)do { if (sizeof(*(&rep.sequenceNumber)) != 2) wrong_size( ); if (__builtin_constant_p((uintptr_t)(&rep.sequenceNumber ) & 1) && ((uintptr_t)(&rep.sequenceNumber) & 1) == 0) *(&rep.sequenceNumber) = lswaps(*(&rep.sequenceNumber )); else swap_uint16((uint16_t *)(&rep.sequenceNumber)); } while (0); | |||
2011 | swapl(&rep.length)do { if (sizeof(*(&rep.length)) != 4) wrong_size(); if (__builtin_constant_p ((uintptr_t)(&rep.length) & 3) && ((uintptr_t )(&rep.length) & 3) == 0) *(&rep.length) = lswapl (*(&rep.length)); else swap_uint32((uint32_t *)(&rep. length)); } while (0); | |||
2012 | } | |||
2013 | ||||
2014 | WriteToClient(client, sizeof(xSyncQueryFenceReply), &rep); | |||
2015 | return client->noClientException; | |||
2016 | } | |||
2017 | ||||
2018 | static int | |||
2019 | ProcSyncAwaitFence(ClientPtr client) | |||
2020 | { | |||
2021 | REQUEST(xSyncAwaitFenceReq)xSyncAwaitFenceReq *stuff = (xSyncAwaitFenceReq *)client-> requestBuffer; | |||
2022 | SyncAwaitUnion *pAwaitUnion; | |||
2023 | SyncAwait *pAwait; | |||
2024 | ||||
2025 | /* Use CARD32 rather than XSyncFence because XIDs are hard-coded to | |||
2026 | * CARD32 in protocol definitions */ | |||
2027 | CARD32 *pProtocolFences; | |||
2028 | int status; | |||
2029 | int len; | |||
2030 | int items; | |||
2031 | int i; | |||
2032 | ||||
2033 | REQUEST_AT_LEAST_SIZE(xSyncAwaitFenceReq)if ((sizeof(xSyncAwaitFenceReq) >> 2) > client->req_len ) return(16); | |||
2034 | ||||
2035 | len = client->req_len << 2; | |||
2036 | len -= sz_xSyncAwaitFenceReq4; | |||
2037 | items = len / sizeof(CARD32); | |||
2038 | ||||
2039 | if (items * sizeof(CARD32) != len) { | |||
2040 | return BadLength16; | |||
2041 | } | |||
2042 | if (items == 0) { | |||
2043 | client->errorValue = items; | |||
2044 | return BadValue2; | |||
2045 | } | |||
2046 | ||||
2047 | if (!(pAwaitUnion = SyncAwaitPrologue(client, items))) | |||
2048 | return BadAlloc11; | |||
2049 | ||||
2050 | /* don't need to do any more memory allocation for this request! */ | |||
2051 | ||||
2052 | pProtocolFences = (CARD32 *) &stuff[1]; | |||
2053 | ||||
2054 | pAwait = &(pAwaitUnion + 1)->await; /* skip over header */ | |||
2055 | for (i = 0; i < items; i++, pProtocolFences++, pAwait++) { | |||
2056 | if (*pProtocolFences == None0L) { | |||
2057 | /* this should take care of removing any triggers created by | |||
2058 | * this request that have already been registered on sync objects | |||
2059 | */ | |||
2060 | FreeResource(pAwaitUnion->header.delete_id, RT_NONE((RESTYPE)0)); | |||
2061 | client->errorValue = *pProtocolFences; | |||
2062 | return SyncErrorBase + XSyncBadFence2L; | |||
2063 | } | |||
2064 | ||||
2065 | pAwait->trigger.pSync = NULL((void*)0); | |||
2066 | /* Provide acceptable values for these unused fields to | |||
2067 | * satisfy SyncInitTrigger's validation logic | |||
2068 | */ | |||
2069 | pAwait->trigger.value_type = XSyncAbsolute; | |||
2070 | XSyncIntToValue(&pAwait->trigger.wait_value, 0)((&pAwait->trigger.wait_value)->hi=((0<0)?~0:0), (&pAwait->trigger.wait_value)->lo=(0)); | |||
2071 | pAwait->trigger.test_type = 0; | |||
2072 | ||||
2073 | status = SyncInitTrigger(client, &pAwait->trigger, | |||
2074 | *pProtocolFences, RTFence, XSyncCAAllTrigger((1L<<0) | (1L<<1) | (1L<<2) | (1L<<3 ))); | |||
2075 | if (status != Success0) { | |||
2076 | /* this should take care of removing any triggers created by | |||
2077 | * this request that have already been registered on sync objects | |||
2078 | */ | |||
2079 | FreeResource(pAwaitUnion->header.delete_id, RT_NONE((RESTYPE)0)); | |||
2080 | return status; | |||
2081 | } | |||
2082 | /* this is not a mistake -- same function works for both cases */ | |||
2083 | pAwait->trigger.TriggerFired = SyncAwaitTriggerFired; | |||
2084 | pAwait->trigger.CounterDestroyed = SyncAwaitTriggerFired; | |||
2085 | /* event_threshold is unused for fence syncs */ | |||
2086 | XSyncIntToValue(&pAwait->event_threshold, 0)((&pAwait->event_threshold)->hi=((0<0)?~0:0),(& pAwait->event_threshold)->lo=(0)); | |||
2087 | pAwait->pHeader = &pAwaitUnion->header; | |||
2088 | pAwaitUnion->header.num_waitconditions++; | |||
2089 | } | |||
2090 | ||||
2091 | SyncAwaitEpilogue(client, items, pAwaitUnion); | |||
2092 | ||||
2093 | return client->noClientException; | |||
2094 | } | |||
2095 | ||||
2096 | /* | |||
2097 | * ** Given an extension request, call the appropriate request procedure | |||
2098 | */ | |||
2099 | static int | |||
2100 | ProcSyncDispatch(ClientPtr client) | |||
2101 | { | |||
2102 | REQUEST(xReq)xReq *stuff = (xReq *)client->requestBuffer; | |||
2103 | ||||
2104 | switch (stuff->data) { | |||
2105 | case X_SyncInitialize0: | |||
2106 | return ProcSyncInitialize(client); | |||
2107 | case X_SyncListSystemCounters1: | |||
2108 | return ProcSyncListSystemCounters(client); | |||
2109 | case X_SyncCreateCounter2: | |||
2110 | return ProcSyncCreateCounter(client); | |||
2111 | case X_SyncSetCounter3: | |||
2112 | return ProcSyncSetCounter(client); | |||
2113 | case X_SyncChangeCounter4: | |||
2114 | return ProcSyncChangeCounter(client); | |||
2115 | case X_SyncQueryCounter5: | |||
2116 | return ProcSyncQueryCounter(client); | |||
2117 | case X_SyncDestroyCounter6: | |||
2118 | return ProcSyncDestroyCounter(client); | |||
2119 | case X_SyncAwait7: | |||
2120 | return ProcSyncAwait(client); | |||
2121 | case X_SyncCreateAlarm8: | |||
2122 | return ProcSyncCreateAlarm(client); | |||
2123 | case X_SyncChangeAlarm9: | |||
2124 | return ProcSyncChangeAlarm(client); | |||
2125 | case X_SyncQueryAlarm10: | |||
2126 | return ProcSyncQueryAlarm(client); | |||
2127 | case X_SyncDestroyAlarm11: | |||
2128 | return ProcSyncDestroyAlarm(client); | |||
2129 | case X_SyncSetPriority12: | |||
2130 | return ProcSyncSetPriority(client); | |||
2131 | case X_SyncGetPriority13: | |||
2132 | return ProcSyncGetPriority(client); | |||
2133 | case X_SyncCreateFence14: | |||
2134 | return ProcSyncCreateFence(client); | |||
2135 | case X_SyncTriggerFence15: | |||
2136 | return ProcSyncTriggerFence(client); | |||
2137 | case X_SyncResetFence16: | |||
2138 | return ProcSyncResetFence(client); | |||
2139 | case X_SyncDestroyFence17: | |||
2140 | return ProcSyncDestroyFence(client); | |||
2141 | case X_SyncQueryFence18: | |||
2142 | return ProcSyncQueryFence(client); | |||
2143 | case X_SyncAwaitFence19: | |||
2144 | return ProcSyncAwaitFence(client); | |||
2145 | default: | |||
2146 | return BadRequest1; | |||
2147 | } | |||
2148 | } | |||
2149 | ||||
2150 | /* | |||
2151 | * Boring Swapping stuff ... | |||
2152 | */ | |||
2153 | ||||
2154 | static int | |||
2155 | SProcSyncInitialize(ClientPtr client) | |||
2156 | { | |||
2157 | REQUEST(xSyncInitializeReq)xSyncInitializeReq *stuff = (xSyncInitializeReq *)client-> requestBuffer; | |||
2158 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||
2159 | REQUEST_SIZE_MATCH(xSyncInitializeReq)if ((sizeof(xSyncInitializeReq) >> 2) != client->req_len ) return(16); | |||
2160 | ||||
2161 | return ProcSyncInitialize(client); | |||
2162 | } | |||
2163 | ||||
2164 | static int | |||
2165 | SProcSyncListSystemCounters(ClientPtr client) | |||
2166 | { | |||
2167 | REQUEST(xSyncListSystemCountersReq)xSyncListSystemCountersReq *stuff = (xSyncListSystemCountersReq *)client->requestBuffer; | |||
2168 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||
2169 | REQUEST_SIZE_MATCH(xSyncListSystemCountersReq)if ((sizeof(xSyncListSystemCountersReq) >> 2) != client ->req_len) return(16); | |||
2170 | ||||
2171 | return ProcSyncListSystemCounters(client); | |||
2172 | } | |||
2173 | ||||
2174 | static int | |||
2175 | SProcSyncCreateCounter(ClientPtr client) | |||
2176 | { | |||
2177 | REQUEST(xSyncCreateCounterReq)xSyncCreateCounterReq *stuff = (xSyncCreateCounterReq *)client ->requestBuffer; | |||
2178 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||
2179 | REQUEST_SIZE_MATCH(xSyncCreateCounterReq)if ((sizeof(xSyncCreateCounterReq) >> 2) != client-> req_len) return(16); | |||
2180 | swapl(&stuff->cid)do { if (sizeof(*(&stuff->cid)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->cid) & 3 ) && ((uintptr_t)(&stuff->cid) & 3) == 0) * (&stuff->cid) = lswapl(*(&stuff->cid)); else swap_uint32 ((uint32_t *)(&stuff->cid)); } while (0); | |||
2181 | swapl(&stuff->initial_value_lo)do { if (sizeof(*(&stuff->initial_value_lo)) != 4) wrong_size (); if (__builtin_constant_p((uintptr_t)(&stuff->initial_value_lo ) & 3) && ((uintptr_t)(&stuff->initial_value_lo ) & 3) == 0) *(&stuff->initial_value_lo) = lswapl( *(&stuff->initial_value_lo)); else swap_uint32((uint32_t *)(&stuff->initial_value_lo)); } while (0); | |||
2182 | swapl(&stuff->initial_value_hi)do { if (sizeof(*(&stuff->initial_value_hi)) != 4) wrong_size (); if (__builtin_constant_p((uintptr_t)(&stuff->initial_value_hi ) & 3) && ((uintptr_t)(&stuff->initial_value_hi ) & 3) == 0) *(&stuff->initial_value_hi) = lswapl( *(&stuff->initial_value_hi)); else swap_uint32((uint32_t *)(&stuff->initial_value_hi)); } while (0); | |||
2183 | ||||
2184 | return ProcSyncCreateCounter(client); | |||
2185 | } | |||
2186 | ||||
2187 | static int | |||
2188 | SProcSyncSetCounter(ClientPtr client) | |||
2189 | { | |||
2190 | REQUEST(xSyncSetCounterReq)xSyncSetCounterReq *stuff = (xSyncSetCounterReq *)client-> requestBuffer; | |||
2191 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||
2192 | REQUEST_SIZE_MATCH(xSyncSetCounterReq)if ((sizeof(xSyncSetCounterReq) >> 2) != client->req_len ) return(16); | |||
2193 | swapl(&stuff->cid)do { if (sizeof(*(&stuff->cid)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->cid) & 3 ) && ((uintptr_t)(&stuff->cid) & 3) == 0) * (&stuff->cid) = lswapl(*(&stuff->cid)); else swap_uint32 ((uint32_t *)(&stuff->cid)); } while (0); | |||
2194 | swapl(&stuff->value_lo)do { if (sizeof(*(&stuff->value_lo)) != 4) wrong_size( ); if (__builtin_constant_p((uintptr_t)(&stuff->value_lo ) & 3) && ((uintptr_t)(&stuff->value_lo) & 3) == 0) *(&stuff->value_lo) = lswapl(*(&stuff-> value_lo)); else swap_uint32((uint32_t *)(&stuff->value_lo )); } while (0); | |||
2195 | swapl(&stuff->value_hi)do { if (sizeof(*(&stuff->value_hi)) != 4) wrong_size( ); if (__builtin_constant_p((uintptr_t)(&stuff->value_hi ) & 3) && ((uintptr_t)(&stuff->value_hi) & 3) == 0) *(&stuff->value_hi) = lswapl(*(&stuff-> value_hi)); else swap_uint32((uint32_t *)(&stuff->value_hi )); } while (0); | |||
2196 | ||||
2197 | return ProcSyncSetCounter(client); | |||
2198 | } | |||
2199 | ||||
2200 | static int | |||
2201 | SProcSyncChangeCounter(ClientPtr client) | |||
2202 | { | |||
2203 | REQUEST(xSyncChangeCounterReq)xSyncChangeCounterReq *stuff = (xSyncChangeCounterReq *)client ->requestBuffer; | |||
2204 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||
2205 | REQUEST_SIZE_MATCH(xSyncChangeCounterReq)if ((sizeof(xSyncChangeCounterReq) >> 2) != client-> req_len) return(16); | |||
2206 | swapl(&stuff->cid)do { if (sizeof(*(&stuff->cid)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->cid) & 3 ) && ((uintptr_t)(&stuff->cid) & 3) == 0) * (&stuff->cid) = lswapl(*(&stuff->cid)); else swap_uint32 ((uint32_t *)(&stuff->cid)); } while (0); | |||
2207 | swapl(&stuff->value_lo)do { if (sizeof(*(&stuff->value_lo)) != 4) wrong_size( ); if (__builtin_constant_p((uintptr_t)(&stuff->value_lo ) & 3) && ((uintptr_t)(&stuff->value_lo) & 3) == 0) *(&stuff->value_lo) = lswapl(*(&stuff-> value_lo)); else swap_uint32((uint32_t *)(&stuff->value_lo )); } while (0); | |||
2208 | swapl(&stuff->value_hi)do { if (sizeof(*(&stuff->value_hi)) != 4) wrong_size( ); if (__builtin_constant_p((uintptr_t)(&stuff->value_hi ) & 3) && ((uintptr_t)(&stuff->value_hi) & 3) == 0) *(&stuff->value_hi) = lswapl(*(&stuff-> value_hi)); else swap_uint32((uint32_t *)(&stuff->value_hi )); } while (0); | |||
2209 | ||||
2210 | return ProcSyncChangeCounter(client); | |||
2211 | } | |||
2212 | ||||
2213 | static int | |||
2214 | SProcSyncQueryCounter(ClientPtr client) | |||
2215 | { | |||
2216 | REQUEST(xSyncQueryCounterReq)xSyncQueryCounterReq *stuff = (xSyncQueryCounterReq *)client-> requestBuffer; | |||
2217 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||
2218 | REQUEST_SIZE_MATCH(xSyncQueryCounterReq)if ((sizeof(xSyncQueryCounterReq) >> 2) != client->req_len ) return(16); | |||
2219 | swapl(&stuff->counter)do { if (sizeof(*(&stuff->counter)) != 4) wrong_size() ; if (__builtin_constant_p((uintptr_t)(&stuff->counter ) & 3) && ((uintptr_t)(&stuff->counter) & 3) == 0) *(&stuff->counter) = lswapl(*(&stuff-> counter)); else swap_uint32((uint32_t *)(&stuff->counter )); } while (0); | |||
2220 | ||||
2221 | return ProcSyncQueryCounter(client); | |||
2222 | } | |||
2223 | ||||
2224 | static int | |||
2225 | SProcSyncDestroyCounter(ClientPtr client) | |||
2226 | { | |||
2227 | REQUEST(xSyncDestroyCounterReq)xSyncDestroyCounterReq *stuff = (xSyncDestroyCounterReq *)client ->requestBuffer; | |||
2228 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||
2229 | REQUEST_SIZE_MATCH(xSyncDestroyCounterReq)if ((sizeof(xSyncDestroyCounterReq) >> 2) != client-> req_len) return(16); | |||
2230 | swapl(&stuff->counter)do { if (sizeof(*(&stuff->counter)) != 4) wrong_size() ; if (__builtin_constant_p((uintptr_t)(&stuff->counter ) & 3) && ((uintptr_t)(&stuff->counter) & 3) == 0) *(&stuff->counter) = lswapl(*(&stuff-> counter)); else swap_uint32((uint32_t *)(&stuff->counter )); } while (0); | |||
2231 | ||||
2232 | return ProcSyncDestroyCounter(client); | |||
2233 | } | |||
2234 | ||||
2235 | static int | |||
2236 | SProcSyncAwait(ClientPtr client) | |||
2237 | { | |||
2238 | REQUEST(xSyncAwaitReq)xSyncAwaitReq *stuff = (xSyncAwaitReq *)client->requestBuffer; | |||
2239 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||
2240 | REQUEST_AT_LEAST_SIZE(xSyncAwaitReq)if ((sizeof(xSyncAwaitReq) >> 2) > client->req_len ) return(16); | |||
2241 | SwapRestL(stuff)SwapLongs((CARD32 *)(stuff + 1), (client->req_len - (sizeof (*stuff) >> 2))); | |||
2242 | ||||
2243 | return ProcSyncAwait(client); | |||
2244 | } | |||
2245 | ||||
2246 | static int | |||
2247 | SProcSyncCreateAlarm(ClientPtr client) | |||
2248 | { | |||
2249 | REQUEST(xSyncCreateAlarmReq)xSyncCreateAlarmReq *stuff = (xSyncCreateAlarmReq *)client-> requestBuffer; | |||
2250 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||
2251 | REQUEST_AT_LEAST_SIZE(xSyncCreateAlarmReq)if ((sizeof(xSyncCreateAlarmReq) >> 2) > client-> req_len ) return(16); | |||
2252 | swapl(&stuff->id)do { if (sizeof(*(&stuff->id)) != 4) wrong_size(); if ( __builtin_constant_p((uintptr_t)(&stuff->id) & 3) && ((uintptr_t)(&stuff->id) & 3) == 0) *(&stuff-> id) = lswapl(*(&stuff->id)); else swap_uint32((uint32_t *)(&stuff->id)); } while (0); | |||
2253 | swapl(&stuff->valueMask)do { if (sizeof(*(&stuff->valueMask)) != 4) wrong_size (); if (__builtin_constant_p((uintptr_t)(&stuff->valueMask ) & 3) && ((uintptr_t)(&stuff->valueMask) & 3) == 0) *(&stuff->valueMask) = lswapl(*(&stuff-> valueMask)); else swap_uint32((uint32_t *)(&stuff->valueMask )); } while (0); | |||
2254 | SwapRestL(stuff)SwapLongs((CARD32 *)(stuff + 1), (client->req_len - (sizeof (*stuff) >> 2))); | |||
2255 | ||||
2256 | return ProcSyncCreateAlarm(client); | |||
2257 | } | |||
2258 | ||||
2259 | static int | |||
2260 | SProcSyncChangeAlarm(ClientPtr client) | |||
2261 | { | |||
2262 | REQUEST(xSyncChangeAlarmReq)xSyncChangeAlarmReq *stuff = (xSyncChangeAlarmReq *)client-> requestBuffer; | |||
2263 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||
2264 | REQUEST_AT_LEAST_SIZE(xSyncChangeAlarmReq)if ((sizeof(xSyncChangeAlarmReq) >> 2) > client-> req_len ) return(16); | |||
2265 | swapl(&stuff->alarm)do { if (sizeof(*(&stuff->alarm)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->alarm) & 3) && ((uintptr_t)(&stuff->alarm) & 3) == 0) *(&stuff->alarm) = lswapl(*(&stuff->alarm)) ; else swap_uint32((uint32_t *)(&stuff->alarm)); } while (0); | |||
2266 | swapl(&stuff->valueMask)do { if (sizeof(*(&stuff->valueMask)) != 4) wrong_size (); if (__builtin_constant_p((uintptr_t)(&stuff->valueMask ) & 3) && ((uintptr_t)(&stuff->valueMask) & 3) == 0) *(&stuff->valueMask) = lswapl(*(&stuff-> valueMask)); else swap_uint32((uint32_t *)(&stuff->valueMask )); } while (0); | |||
2267 | SwapRestL(stuff)SwapLongs((CARD32 *)(stuff + 1), (client->req_len - (sizeof (*stuff) >> 2))); | |||
2268 | return ProcSyncChangeAlarm(client); | |||
2269 | } | |||
2270 | ||||
2271 | static int | |||
2272 | SProcSyncQueryAlarm(ClientPtr client) | |||
2273 | { | |||
2274 | REQUEST(xSyncQueryAlarmReq)xSyncQueryAlarmReq *stuff = (xSyncQueryAlarmReq *)client-> requestBuffer; | |||
2275 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||
2276 | REQUEST_SIZE_MATCH(xSyncQueryAlarmReq)if ((sizeof(xSyncQueryAlarmReq) >> 2) != client->req_len ) return(16); | |||
2277 | swapl(&stuff->alarm)do { if (sizeof(*(&stuff->alarm)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->alarm) & 3) && ((uintptr_t)(&stuff->alarm) & 3) == 0) *(&stuff->alarm) = lswapl(*(&stuff->alarm)) ; else swap_uint32((uint32_t *)(&stuff->alarm)); } while (0); | |||
2278 | ||||
2279 | return ProcSyncQueryAlarm(client); | |||
2280 | } | |||
2281 | ||||
2282 | static int | |||
2283 | SProcSyncDestroyAlarm(ClientPtr client) | |||
2284 | { | |||
2285 | REQUEST(xSyncDestroyAlarmReq)xSyncDestroyAlarmReq *stuff = (xSyncDestroyAlarmReq *)client-> requestBuffer; | |||
2286 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||
2287 | REQUEST_SIZE_MATCH(xSyncDestroyAlarmReq)if ((sizeof(xSyncDestroyAlarmReq) >> 2) != client->req_len ) return(16); | |||
2288 | swapl(&stuff->alarm)do { if (sizeof(*(&stuff->alarm)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->alarm) & 3) && ((uintptr_t)(&stuff->alarm) & 3) == 0) *(&stuff->alarm) = lswapl(*(&stuff->alarm)) ; else swap_uint32((uint32_t *)(&stuff->alarm)); } while (0); | |||
2289 | ||||
2290 | return ProcSyncDestroyAlarm(client); | |||
2291 | } | |||
2292 | ||||
2293 | static int | |||
2294 | SProcSyncSetPriority(ClientPtr client) | |||
2295 | { | |||
2296 | REQUEST(xSyncSetPriorityReq)xSyncSetPriorityReq *stuff = (xSyncSetPriorityReq *)client-> requestBuffer; | |||
2297 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||
2298 | REQUEST_SIZE_MATCH(xSyncSetPriorityReq)if ((sizeof(xSyncSetPriorityReq) >> 2) != client->req_len ) return(16); | |||
2299 | swapl(&stuff->id)do { if (sizeof(*(&stuff->id)) != 4) wrong_size(); if ( __builtin_constant_p((uintptr_t)(&stuff->id) & 3) && ((uintptr_t)(&stuff->id) & 3) == 0) *(&stuff-> id) = lswapl(*(&stuff->id)); else swap_uint32((uint32_t *)(&stuff->id)); } while (0); | |||
2300 | swapl(&stuff->priority)do { if (sizeof(*(&stuff->priority)) != 4) wrong_size( ); if (__builtin_constant_p((uintptr_t)(&stuff->priority ) & 3) && ((uintptr_t)(&stuff->priority) & 3) == 0) *(&stuff->priority) = lswapl(*(&stuff-> priority)); else swap_uint32((uint32_t *)(&stuff->priority )); } while (0); | |||
2301 | ||||
2302 | return ProcSyncSetPriority(client); | |||
2303 | } | |||
2304 | ||||
2305 | static int | |||
2306 | SProcSyncGetPriority(ClientPtr client) | |||
2307 | { | |||
2308 | REQUEST(xSyncGetPriorityReq)xSyncGetPriorityReq *stuff = (xSyncGetPriorityReq *)client-> requestBuffer; | |||
2309 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||
2310 | REQUEST_SIZE_MATCH(xSyncGetPriorityReq)if ((sizeof(xSyncGetPriorityReq) >> 2) != client->req_len ) return(16); | |||
2311 | swapl(&stuff->id)do { if (sizeof(*(&stuff->id)) != 4) wrong_size(); if ( __builtin_constant_p((uintptr_t)(&stuff->id) & 3) && ((uintptr_t)(&stuff->id) & 3) == 0) *(&stuff-> id) = lswapl(*(&stuff->id)); else swap_uint32((uint32_t *)(&stuff->id)); } while (0); | |||
2312 | ||||
2313 | return ProcSyncGetPriority(client); | |||
2314 | } | |||
2315 | ||||
2316 | static int | |||
2317 | SProcSyncCreateFence(ClientPtr client) | |||
2318 | { | |||
2319 | REQUEST(xSyncCreateFenceReq)xSyncCreateFenceReq *stuff = (xSyncCreateFenceReq *)client-> requestBuffer; | |||
2320 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||
2321 | REQUEST_SIZE_MATCH(xSyncCreateFenceReq)if ((sizeof(xSyncCreateFenceReq) >> 2) != client->req_len ) return(16); | |||
2322 | swapl(&stuff->fid)do { if (sizeof(*(&stuff->fid)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->fid) & 3 ) && ((uintptr_t)(&stuff->fid) & 3) == 0) * (&stuff->fid) = lswapl(*(&stuff->fid)); else swap_uint32 ((uint32_t *)(&stuff->fid)); } while (0); | |||
2323 | ||||
2324 | return ProcSyncCreateFence(client); | |||
2325 | } | |||
2326 | ||||
2327 | static int | |||
2328 | SProcSyncTriggerFence(ClientPtr client) | |||
2329 | { | |||
2330 | REQUEST(xSyncTriggerFenceReq)xSyncTriggerFenceReq *stuff = (xSyncTriggerFenceReq *)client-> requestBuffer; | |||
2331 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||
2332 | REQUEST_SIZE_MATCH(xSyncTriggerFenceReq)if ((sizeof(xSyncTriggerFenceReq) >> 2) != client->req_len ) return(16); | |||
2333 | swapl(&stuff->fid)do { if (sizeof(*(&stuff->fid)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->fid) & 3 ) && ((uintptr_t)(&stuff->fid) & 3) == 0) * (&stuff->fid) = lswapl(*(&stuff->fid)); else swap_uint32 ((uint32_t *)(&stuff->fid)); } while (0); | |||
2334 | ||||
2335 | return ProcSyncTriggerFence(client); | |||
2336 | } | |||
2337 | ||||
2338 | static int | |||
2339 | SProcSyncResetFence(ClientPtr client) | |||
2340 | { | |||
2341 | REQUEST(xSyncResetFenceReq)xSyncResetFenceReq *stuff = (xSyncResetFenceReq *)client-> requestBuffer; | |||
2342 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||
2343 | REQUEST_SIZE_MATCH(xSyncResetFenceReq)if ((sizeof(xSyncResetFenceReq) >> 2) != client->req_len ) return(16); | |||
2344 | swapl(&stuff->fid)do { if (sizeof(*(&stuff->fid)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->fid) & 3 ) && ((uintptr_t)(&stuff->fid) & 3) == 0) * (&stuff->fid) = lswapl(*(&stuff->fid)); else swap_uint32 ((uint32_t *)(&stuff->fid)); } while (0); | |||
2345 | ||||
2346 | return ProcSyncResetFence(client); | |||
2347 | } | |||
2348 | ||||
2349 | static int | |||
2350 | SProcSyncDestroyFence(ClientPtr client) | |||
2351 | { | |||
2352 | REQUEST(xSyncDestroyFenceReq)xSyncDestroyFenceReq *stuff = (xSyncDestroyFenceReq *)client-> requestBuffer; | |||
2353 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||
2354 | REQUEST_SIZE_MATCH(xSyncDestroyFenceReq)if ((sizeof(xSyncDestroyFenceReq) >> 2) != client->req_len ) return(16); | |||
2355 | swapl(&stuff->fid)do { if (sizeof(*(&stuff->fid)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->fid) & 3 ) && ((uintptr_t)(&stuff->fid) & 3) == 0) * (&stuff->fid) = lswapl(*(&stuff->fid)); else swap_uint32 ((uint32_t *)(&stuff->fid)); } while (0); | |||
2356 | ||||
2357 | return ProcSyncDestroyFence(client); | |||
2358 | } | |||
2359 | ||||
2360 | static int | |||
2361 | SProcSyncQueryFence(ClientPtr client) | |||
2362 | { | |||
2363 | REQUEST(xSyncQueryFenceReq)xSyncQueryFenceReq *stuff = (xSyncQueryFenceReq *)client-> requestBuffer; | |||
2364 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||
2365 | REQUEST_SIZE_MATCH(xSyncQueryFenceReq)if ((sizeof(xSyncQueryFenceReq) >> 2) != client->req_len ) return(16); | |||
2366 | swapl(&stuff->fid)do { if (sizeof(*(&stuff->fid)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->fid) & 3 ) && ((uintptr_t)(&stuff->fid) & 3) == 0) * (&stuff->fid) = lswapl(*(&stuff->fid)); else swap_uint32 ((uint32_t *)(&stuff->fid)); } while (0); | |||
2367 | ||||
2368 | return ProcSyncQueryFence(client); | |||
2369 | } | |||
2370 | ||||
2371 | static int | |||
2372 | SProcSyncAwaitFence(ClientPtr client) | |||
2373 | { | |||
2374 | REQUEST(xSyncAwaitFenceReq)xSyncAwaitFenceReq *stuff = (xSyncAwaitFenceReq *)client-> requestBuffer; | |||
2375 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||
2376 | REQUEST_AT_LEAST_SIZE(xSyncAwaitFenceReq)if ((sizeof(xSyncAwaitFenceReq) >> 2) > client->req_len ) return(16); | |||
2377 | SwapRestL(stuff)SwapLongs((CARD32 *)(stuff + 1), (client->req_len - (sizeof (*stuff) >> 2))); | |||
2378 | ||||
2379 | return ProcSyncAwaitFence(client); | |||
2380 | } | |||
2381 | ||||
2382 | static int | |||
2383 | SProcSyncDispatch(ClientPtr client) | |||
2384 | { | |||
2385 | REQUEST(xReq)xReq *stuff = (xReq *)client->requestBuffer; | |||
2386 | ||||
2387 | switch (stuff->data) { | |||
2388 | case X_SyncInitialize0: | |||
2389 | return SProcSyncInitialize(client); | |||
2390 | case X_SyncListSystemCounters1: | |||
2391 | return SProcSyncListSystemCounters(client); | |||
2392 | case X_SyncCreateCounter2: | |||
2393 | return SProcSyncCreateCounter(client); | |||
2394 | case X_SyncSetCounter3: | |||
2395 | return SProcSyncSetCounter(client); | |||
2396 | case X_SyncChangeCounter4: | |||
2397 | return SProcSyncChangeCounter(client); | |||
2398 | case X_SyncQueryCounter5: | |||
2399 | return SProcSyncQueryCounter(client); | |||
2400 | case X_SyncDestroyCounter6: | |||
2401 | return SProcSyncDestroyCounter(client); | |||
2402 | case X_SyncAwait7: | |||
2403 | return SProcSyncAwait(client); | |||
2404 | case X_SyncCreateAlarm8: | |||
2405 | return SProcSyncCreateAlarm(client); | |||
2406 | case X_SyncChangeAlarm9: | |||
2407 | return SProcSyncChangeAlarm(client); | |||
2408 | case X_SyncQueryAlarm10: | |||
2409 | return SProcSyncQueryAlarm(client); | |||
2410 | case X_SyncDestroyAlarm11: | |||
2411 | return SProcSyncDestroyAlarm(client); | |||
2412 | case X_SyncSetPriority12: | |||
2413 | return SProcSyncSetPriority(client); | |||
2414 | case X_SyncGetPriority13: | |||
2415 | return SProcSyncGetPriority(client); | |||
2416 | case X_SyncCreateFence14: | |||
2417 | return SProcSyncCreateFence(client); | |||
2418 | case X_SyncTriggerFence15: | |||
2419 | return SProcSyncTriggerFence(client); | |||
2420 | case X_SyncResetFence16: | |||
2421 | return SProcSyncResetFence(client); | |||
2422 | case X_SyncDestroyFence17: | |||
2423 | return SProcSyncDestroyFence(client); | |||
2424 | case X_SyncQueryFence18: | |||
2425 | return SProcSyncQueryFence(client); | |||
2426 | case X_SyncAwaitFence19: | |||
2427 | return SProcSyncAwaitFence(client); | |||
2428 | default: | |||
2429 | return BadRequest1; | |||
2430 | } | |||
2431 | } | |||
2432 | ||||
2433 | /* | |||
2434 | * Event Swapping | |||
2435 | */ | |||
2436 | ||||
2437 | static void | |||
2438 | SCounterNotifyEvent(xSyncCounterNotifyEvent * from, | |||
2439 | xSyncCounterNotifyEvent * to) | |||
2440 | { | |||
2441 | to->type = from->type; | |||
2442 | to->kind = from->kind; | |||
2443 | cpswaps(from->sequenceNumber, to->sequenceNumber)do { if (sizeof((from->sequenceNumber)) != 2 || sizeof((to ->sequenceNumber)) != 2) wrong_size(); (to->sequenceNumber ) = lswaps((from->sequenceNumber)); } while (0); | |||
2444 | cpswapl(from->counter, to->counter)do { if (sizeof((from->counter)) != 4 || sizeof((to->counter )) != 4) wrong_size(); (to->counter) = lswapl((from->counter )); } while (0); | |||
2445 | cpswapl(from->wait_value_lo, to->wait_value_lo)do { if (sizeof((from->wait_value_lo)) != 4 || sizeof((to-> wait_value_lo)) != 4) wrong_size(); (to->wait_value_lo) = lswapl ((from->wait_value_lo)); } while (0); | |||
2446 | cpswapl(from->wait_value_hi, to->wait_value_hi)do { if (sizeof((from->wait_value_hi)) != 4 || sizeof((to-> wait_value_hi)) != 4) wrong_size(); (to->wait_value_hi) = lswapl ((from->wait_value_hi)); } while (0); | |||
2447 | cpswapl(from->counter_value_lo, to->counter_value_lo)do { if (sizeof((from->counter_value_lo)) != 4 || sizeof(( to->counter_value_lo)) != 4) wrong_size(); (to->counter_value_lo ) = lswapl((from->counter_value_lo)); } while (0); | |||
2448 | cpswapl(from->counter_value_hi, to->counter_value_hi)do { if (sizeof((from->counter_value_hi)) != 4 || sizeof(( to->counter_value_hi)) != 4) wrong_size(); (to->counter_value_hi ) = lswapl((from->counter_value_hi)); } while (0); | |||
2449 | cpswapl(from->time, to->time)do { if (sizeof((from->time)) != 4 || sizeof((to->time) ) != 4) wrong_size(); (to->time) = lswapl((from->time)) ; } while (0); | |||
2450 | cpswaps(from->count, to->count)do { if (sizeof((from->count)) != 2 || sizeof((to->count )) != 2) wrong_size(); (to->count) = lswaps((from->count )); } while (0); | |||
2451 | to->destroyed = from->destroyed; | |||
2452 | } | |||
2453 | ||||
2454 | static void | |||
2455 | SAlarmNotifyEvent(xSyncAlarmNotifyEvent * from, xSyncAlarmNotifyEvent * to) | |||
2456 | { | |||
2457 | to->type = from->type; | |||
2458 | to->kind = from->kind; | |||
2459 | cpswaps(from->sequenceNumber, to->sequenceNumber)do { if (sizeof((from->sequenceNumber)) != 2 || sizeof((to ->sequenceNumber)) != 2) wrong_size(); (to->sequenceNumber ) = lswaps((from->sequenceNumber)); } while (0); | |||
2460 | cpswapl(from->alarm, to->alarm)do { if (sizeof((from->alarm)) != 4 || sizeof((to->alarm )) != 4) wrong_size(); (to->alarm) = lswapl((from->alarm )); } while (0); | |||
2461 | cpswapl(from->counter_value_lo, to->counter_value_lo)do { if (sizeof((from->counter_value_lo)) != 4 || sizeof(( to->counter_value_lo)) != 4) wrong_size(); (to->counter_value_lo ) = lswapl((from->counter_value_lo)); } while (0); | |||
2462 | cpswapl(from->counter_value_hi, to->counter_value_hi)do { if (sizeof((from->counter_value_hi)) != 4 || sizeof(( to->counter_value_hi)) != 4) wrong_size(); (to->counter_value_hi ) = lswapl((from->counter_value_hi)); } while (0); | |||
2463 | cpswapl(from->alarm_value_lo, to->alarm_value_lo)do { if (sizeof((from->alarm_value_lo)) != 4 || sizeof((to ->alarm_value_lo)) != 4) wrong_size(); (to->alarm_value_lo ) = lswapl((from->alarm_value_lo)); } while (0); | |||
2464 | cpswapl(from->alarm_value_hi, to->alarm_value_hi)do { if (sizeof((from->alarm_value_hi)) != 4 || sizeof((to ->alarm_value_hi)) != 4) wrong_size(); (to->alarm_value_hi ) = lswapl((from->alarm_value_hi)); } while (0); | |||
2465 | cpswapl(from->time, to->time)do { if (sizeof((from->time)) != 4 || sizeof((to->time) ) != 4) wrong_size(); (to->time) = lswapl((from->time)) ; } while (0); | |||
2466 | to->state = from->state; | |||
2467 | } | |||
2468 | ||||
2469 | /* | |||
2470 | * ** Close everything down. ** This is fairly simple for now. | |||
2471 | */ | |||
2472 | /* ARGSUSED */ | |||
2473 | static void | |||
2474 | SyncResetProc(ExtensionEntry * extEntry) | |||
2475 | { | |||
2476 | RTCounter = 0; | |||
2477 | } | |||
2478 | ||||
2479 | /* | |||
2480 | * ** Initialise the extension. | |||
2481 | */ | |||
2482 | void | |||
2483 | SyncExtensionInit(void) | |||
2484 | { | |||
2485 | ExtensionEntry *extEntry; | |||
2486 | int s; | |||
2487 | ||||
2488 | for (s = 0; s < screenInfo.numScreens; s++) | |||
2489 | miSyncSetup(screenInfo.screens[s]); | |||
2490 | ||||
2491 | RTCounter = CreateNewResourceType(FreeCounter, "SyncCounter"); | |||
2492 | xorg_list_init(&SysCounterList); | |||
2493 | RTAlarm = CreateNewResourceType(FreeAlarm, "SyncAlarm"); | |||
2494 | RTAwait = CreateNewResourceType(FreeAwait, "SyncAwait"); | |||
2495 | RTFence = CreateNewResourceType(FreeFence, "SyncFence"); | |||
2496 | if (RTAwait) | |||
2497 | RTAwait |= RC_NEVERRETAIN((RESTYPE)1<<29); | |||
2498 | RTAlarmClient = CreateNewResourceType(FreeAlarmClient, "SyncAlarmClient"); | |||
2499 | if (RTAlarmClient) | |||
2500 | RTAlarmClient |= RC_NEVERRETAIN((RESTYPE)1<<29); | |||
2501 | ||||
2502 | if (RTCounter == 0 || RTAwait == 0 || RTAlarm == 0 || | |||
2503 | RTAlarmClient == 0 || | |||
2504 | (extEntry = AddExtension(SYNC_NAME"SYNC", | |||
2505 | XSyncNumberEvents2L, XSyncNumberErrors(2L + 1), | |||
2506 | ProcSyncDispatch, SProcSyncDispatch, | |||
2507 | SyncResetProc, StandardMinorOpcode)) == NULL((void*)0)) { | |||
2508 | ErrorF("Sync Extension %d.%d failed to Initialise\n", | |||
2509 | SYNC_MAJOR_VERSION3, SYNC_MINOR_VERSION1); | |||
2510 | return; | |||
2511 | } | |||
2512 | ||||
2513 | SyncEventBase = extEntry->eventBase; | |||
2514 | SyncErrorBase = extEntry->errorBase; | |||
2515 | EventSwapVector[SyncEventBase + XSyncCounterNotify0] = | |||
2516 | (EventSwapPtr) SCounterNotifyEvent; | |||
2517 | EventSwapVector[SyncEventBase + XSyncAlarmNotify1] = | |||
2518 | (EventSwapPtr) SAlarmNotifyEvent; | |||
2519 | ||||
2520 | SetResourceTypeErrorValue(RTCounter, SyncErrorBase + XSyncBadCounter0L); | |||
2521 | SetResourceTypeErrorValue(RTAlarm, SyncErrorBase + XSyncBadAlarm1L); | |||
2522 | SetResourceTypeErrorValue(RTFence, SyncErrorBase + XSyncBadFence2L); | |||
2523 | ||||
2524 | /* | |||
2525 | * Although SERVERTIME is implemented by the OS layer, we initialise it | |||
2526 | * here because doing it in OsInit() is too early. The resource database | |||
2527 | * is not initialised when OsInit() is called. This is just about OK | |||
2528 | * because there is always a servertime counter. | |||
2529 | */ | |||
2530 | SyncInitServerTime(); | |||
2531 | SyncInitIdleTime(); | |||
2532 | ||||
2533 | #ifdef DEBUG | |||
2534 | fprintf(stderr__stderrp, "Sync Extension %d.%d\n", | |||
2535 | SYNC_MAJOR_VERSION3, SYNC_MINOR_VERSION1); | |||
2536 | #endif | |||
2537 | } | |||
2538 | ||||
2539 | /* | |||
2540 | * ***** SERVERTIME implementation - should go in its own file in OS directory? | |||
2541 | */ | |||
2542 | ||||
2543 | static void *ServertimeCounter; | |||
2544 | static XSyncValue Now; | |||
2545 | static XSyncValue *pnext_time; | |||
2546 | ||||
2547 | #define GetTime(){ unsigned long millis = GetTimeInMillis(); unsigned long maxis = ((Now).hi); if (millis < ((Now).lo)) maxis++; ((&Now )->lo = (millis), (&Now)->hi = (maxis));}\ | |||
2548 | {\ | |||
2549 | unsigned long millis = GetTimeInMillis();\ | |||
2550 | unsigned long maxis = XSyncValueHigh32(Now)((Now).hi);\ | |||
2551 | if (millis < XSyncValueLow32(Now)((Now).lo)) maxis++;\ | |||
2552 | XSyncIntsToValue(&Now, millis, maxis)((&Now)->lo = (millis), (&Now)->hi = (maxis));\ | |||
2553 | } | |||
2554 | ||||
2555 | /* | |||
2556 | *** Server Block Handler | |||
2557 | *** code inspired by multibuffer extension (now deprecated) | |||
2558 | */ | |||
2559 | /*ARGSUSED*/ static void | |||
2560 | ServertimeBlockHandler(void *env, struct timeval **wt, void *LastSelectMask) | |||
2561 | { | |||
2562 | XSyncValue delay; | |||
2563 | unsigned long timeout; | |||
2564 | ||||
2565 | if (pnext_time) { | |||
2566 | GetTime(){ unsigned long millis = GetTimeInMillis(); unsigned long maxis = ((Now).hi); if (millis < ((Now).lo)) maxis++; ((&Now )->lo = (millis), (&Now)->hi = (maxis));}; | |||
2567 | ||||
2568 | if (XSyncValueGreaterOrEqual(Now, *pnext_time)((Now).hi>(*pnext_time).hi || ((Now).hi==(*pnext_time).hi && (Now).lo>=(*pnext_time).lo))) { | |||
2569 | timeout = 0; | |||
2570 | } | |||
2571 | else { | |||
2572 | Bool overflow; | |||
2573 | ||||
2574 | XSyncValueSubtract(&delay, *pnext_time, Now, &overflow){ int t = (*pnext_time).lo; Bool signa = (((*pnext_time).hi & 0x80000000) ? 1 : 0); Bool signb = (((Now).hi & 0x80000000 ) ? 1 : 0); ((&delay)->lo = (*pnext_time).lo - (Now).lo ); ((&delay)->hi = (*pnext_time).hi - (Now).hi); if (t <(&delay)->lo) (&delay)->hi--; *&overflow = ((signa == signb) && !(signa == (((*&delay).hi & 0x80000000) ? 1 : 0))); }; | |||
2575 | (void) overflow; | |||
2576 | timeout = XSyncValueLow32(delay)((delay).lo); | |||
2577 | } | |||
2578 | AdjustWaitForDelay(wt, timeout); /* os/utils.c */ | |||
2579 | } | |||
2580 | } | |||
2581 | ||||
2582 | /* | |||
2583 | *** Wakeup Handler | |||
2584 | */ | |||
2585 | /*ARGSUSED*/ static void | |||
2586 | ServertimeWakeupHandler(void *env, int rc, void *LastSelectMask) | |||
2587 | { | |||
2588 | if (pnext_time) { | |||
2589 | GetTime(){ unsigned long millis = GetTimeInMillis(); unsigned long maxis = ((Now).hi); if (millis < ((Now).lo)) maxis++; ((&Now )->lo = (millis), (&Now)->hi = (maxis));}; | |||
2590 | ||||
2591 | if (XSyncValueGreaterOrEqual(Now, *pnext_time)((Now).hi>(*pnext_time).hi || ((Now).hi==(*pnext_time).hi && (Now).lo>=(*pnext_time).lo))) { | |||
2592 | SyncChangeCounter(ServertimeCounter, Now); | |||
2593 | } | |||
2594 | } | |||
2595 | } | |||
2596 | ||||
2597 | static void | |||
2598 | ServertimeQueryValue(void *pCounter, CARD64XSyncValue * pValue_return) | |||
2599 | { | |||
2600 | GetTime(){ unsigned long millis = GetTimeInMillis(); unsigned long maxis = ((Now).hi); if (millis < ((Now).lo)) maxis++; ((&Now )->lo = (millis), (&Now)->hi = (maxis));}; | |||
2601 | *pValue_return = Now; | |||
2602 | } | |||
2603 | ||||
2604 | static void | |||
2605 | ServertimeBracketValues(void *pCounter, CARD64XSyncValue * pbracket_less, | |||
2606 | CARD64XSyncValue * pbracket_greater) | |||
2607 | { | |||
2608 | if (!pnext_time && pbracket_greater) { | |||
2609 | RegisterBlockAndWakeupHandlers(ServertimeBlockHandler, | |||
2610 | ServertimeWakeupHandler, NULL((void*)0)); | |||
2611 | } | |||
2612 | else if (pnext_time && !pbracket_greater) { | |||
2613 | RemoveBlockAndWakeupHandlers(ServertimeBlockHandler, | |||
2614 | ServertimeWakeupHandler, NULL((void*)0)); | |||
2615 | } | |||
2616 | pnext_time = pbracket_greater; | |||
2617 | } | |||
2618 | ||||
2619 | static void | |||
2620 | SyncInitServerTime(void) | |||
2621 | { | |||
2622 | CARD64XSyncValue resolution; | |||
2623 | ||||
2624 | XSyncIntsToValue(&Now, GetTimeInMillis(), 0)((&Now)->lo = (GetTimeInMillis()), (&Now)->hi = (0)); | |||
2625 | XSyncIntToValue(&resolution, 4)((&resolution)->hi=((4<0)?~0:0),(&resolution)-> lo=(4)); | |||
2626 | ServertimeCounter = SyncCreateSystemCounter("SERVERTIME", Now, resolution, | |||
2627 | XSyncCounterNeverDecreases, | |||
2628 | ServertimeQueryValue, | |||
2629 | ServertimeBracketValues); | |||
2630 | pnext_time = NULL((void*)0); | |||
2631 | } | |||
2632 | ||||
2633 | /* | |||
2634 | * IDLETIME implementation | |||
2635 | */ | |||
2636 | ||||
2637 | typedef struct { | |||
2638 | XSyncValue *value_less; | |||
2639 | XSyncValue *value_greater; | |||
2640 | int deviceid; | |||
2641 | } IdleCounterPriv; | |||
2642 | ||||
2643 | static void | |||
2644 | IdleTimeQueryValue(void *pCounter, CARD64XSyncValue * pValue_return) | |||
2645 | { | |||
2646 | int deviceid; | |||
2647 | CARD32 idle; | |||
2648 | ||||
2649 | if (pCounter) { | |||
2650 | SyncCounter *counter = pCounter; | |||
2651 | IdleCounterPriv *priv = SysCounterGetPrivate(counter); | |||
2652 | deviceid = priv->deviceid; | |||
2653 | } | |||
2654 | else | |||
2655 | deviceid = XIAllDevices0; | |||
2656 | idle = GetTimeInMillis() - LastEventTime(deviceid).milliseconds; | |||
2657 | XSyncIntsToValue(pValue_return, idle, 0)((pValue_return)->lo = (idle), (pValue_return)->hi = (0 )); | |||
2658 | } | |||
2659 | ||||
2660 | static void | |||
2661 | IdleTimeBlockHandler(void *pCounter, struct timeval **wt, void *LastSelectMask) | |||
2662 | { | |||
2663 | SyncCounter *counter = pCounter; | |||
2664 | IdleCounterPriv *priv = SysCounterGetPrivate(counter); | |||
2665 | XSyncValue *less = priv->value_less, | |||
2666 | *greater = priv->value_greater; | |||
2667 | XSyncValue idle, old_idle; | |||
2668 | SyncTriggerList *list = counter->sync.pTriglist; | |||
2669 | SyncTrigger *trig; | |||
2670 | ||||
2671 | if (!less && !greater) | |||
2672 | return; | |||
2673 | ||||
2674 | old_idle = counter->value; | |||
2675 | IdleTimeQueryValue(counter, &idle); | |||
2676 | counter->value = idle; /* push, so CheckTrigger works */ | |||
2677 | ||||
2678 | /** | |||
2679 | * There's an indefinite amount of time between ProcessInputEvents() | |||
2680 | * where the idle time is reset and the time we actually get here. idle | |||
2681 | * may be past the lower bracket if we dawdled with the events, so | |||
2682 | * check for whether we did reset and bomb out of select immediately. | |||
2683 | */ | |||
2684 | if (less && XSyncValueGreaterThan(idle, *less)((idle).hi>(*less).hi || ((idle).hi==(*less).hi && (idle).lo>(*less).lo)) && | |||
2685 | LastEventTimeWasReset(priv->deviceid)) { | |||
2686 | AdjustWaitForDelay(wt, 0); | |||
2687 | } else if (less && XSyncValueLessOrEqual(idle, *less)((idle).hi<(*less).hi || ((idle).hi==(*less).hi && (idle).lo<=(*less).lo))) { | |||
2688 | /* | |||
2689 | * We've been idle for less than the threshold value, and someone | |||
2690 | * wants to know about that, but now we need to know whether they | |||
2691 | * want level or edge trigger. Check the trigger list against the | |||
2692 | * current idle time, and if any succeed, bomb out of select() | |||
2693 | * immediately so we can reschedule. | |||
2694 | */ | |||
2695 | ||||
2696 | for (list = counter->sync.pTriglist; list; list = list->next) { | |||
2697 | trig = list->pTrigger; | |||
2698 | if (trig->CheckTrigger(trig, old_idle)) { | |||
2699 | AdjustWaitForDelay(wt, 0); | |||
2700 | break; | |||
2701 | } | |||
2702 | } | |||
2703 | /* | |||
2704 | * We've been called exactly on the idle time, but we have a | |||
2705 | * NegativeTransition trigger which requires a transition from an | |||
2706 | * idle time greater than this. Schedule a wakeup for the next | |||
2707 | * millisecond so we won't miss a transition. | |||
2708 | */ | |||
2709 | if (XSyncValueEqual(idle, *less)((idle).lo==(*less).lo && (idle).hi==(*less).hi)) | |||
2710 | AdjustWaitForDelay(wt, 1); | |||
2711 | } | |||
2712 | else if (greater) { | |||
2713 | /* | |||
2714 | * There's a threshold in the positive direction. If we've been | |||
2715 | * idle less than it, schedule a wakeup for sometime in the future. | |||
2716 | * If we've been idle more than it, and someone wants to know about | |||
2717 | * that level-triggered, schedule an immediate wakeup. | |||
2718 | */ | |||
2719 | ||||
2720 | if (XSyncValueLessThan(idle, *greater)((idle).hi<(*greater).hi || ((idle).hi==(*greater).hi && (idle).lo<(*greater).lo))) { | |||
2721 | XSyncValue value; | |||
2722 | Bool overflow; | |||
2723 | ||||
2724 | XSyncValueSubtract(&value, *greater, idle, &overflow){ int t = (*greater).lo; Bool signa = (((*greater).hi & 0x80000000 ) ? 1 : 0); Bool signb = (((idle).hi & 0x80000000) ? 1 : 0 ); ((&value)->lo = (*greater).lo - (idle).lo); ((& value)->hi = (*greater).hi - (idle).hi); if (t<(&value )->lo) (&value)->hi--; *&overflow = ((signa == signb ) && !(signa == (((*&value).hi & 0x80000000) ? 1 : 0))); }; | |||
2725 | AdjustWaitForDelay(wt, XSyncValueLow32(value)((value).lo)); | |||
2726 | } | |||
2727 | else { | |||
2728 | for (list = counter->sync.pTriglist; list; | |||
2729 | list = list->next) { | |||
2730 | trig = list->pTrigger; | |||
2731 | if (trig->CheckTrigger(trig, old_idle)) { | |||
2732 | AdjustWaitForDelay(wt, 0); | |||
2733 | break; | |||
2734 | } | |||
2735 | } | |||
2736 | } | |||
2737 | } | |||
2738 | ||||
2739 | counter->value = old_idle; /* pop */ | |||
2740 | } | |||
2741 | ||||
2742 | static void | |||
2743 | IdleTimeCheckBrackets(SyncCounter *counter, XSyncValue idle, XSyncValue *less, XSyncValue *greater) | |||
2744 | { | |||
2745 | if ((greater && XSyncValueGreaterOrEqual(idle, *greater)((idle).hi>(*greater).hi || ((idle).hi==(*greater).hi && (idle).lo>=(*greater).lo))) || | |||
2746 | (less && XSyncValueLessOrEqual(idle, *less)((idle).hi<(*less).hi || ((idle).hi==(*less).hi && (idle).lo<=(*less).lo)))) { | |||
2747 | SyncChangeCounter(counter, idle); | |||
2748 | } | |||
2749 | else | |||
2750 | SyncUpdateCounter(counter, idle); | |||
2751 | } | |||
2752 | ||||
2753 | static void | |||
2754 | IdleTimeWakeupHandler(void *pCounter, int rc, void *LastSelectMask) | |||
2755 | { | |||
2756 | SyncCounter *counter = pCounter; | |||
2757 | IdleCounterPriv *priv = SysCounterGetPrivate(counter); | |||
2758 | XSyncValue *less = priv->value_less, | |||
2759 | *greater = priv->value_greater; | |||
2760 | XSyncValue idle; | |||
2761 | ||||
2762 | if (!less && !greater) | |||
2763 | return; | |||
2764 | ||||
2765 | IdleTimeQueryValue(pCounter, &idle); | |||
2766 | ||||
2767 | /* | |||
2768 | There is no guarantee for the WakeupHandler to be called within a specific | |||
2769 | timeframe. Idletime may go to 0, but by the time we get here, it may be | |||
2770 | non-zero and alarms for a pos. transition on 0 won't get triggered. | |||
2771 | https://bugs.freedesktop.org/show_bug.cgi?id=70476 | |||
2772 | */ | |||
2773 | if (LastEventTimeWasReset(priv->deviceid)) { | |||
2774 | LastEventTimeToggleResetFlag(priv->deviceid, FALSE0); | |||
2775 | if (!XSyncValueIsZero(idle)((idle).lo==0 && (idle).hi==0)) { | |||
2776 | XSyncValue zero; | |||
2777 | XSyncIntsToValue(&zero, 0, 0)((&zero)->lo = (0), (&zero)->hi = (0)); | |||
2778 | IdleTimeCheckBrackets(counter, zero, less, greater); | |||
2779 | less = priv->value_less; | |||
2780 | greater = priv->value_greater; | |||
2781 | } | |||
2782 | } | |||
2783 | ||||
2784 | IdleTimeCheckBrackets(counter, idle, less, greater); | |||
2785 | } | |||
2786 | ||||
2787 | static void | |||
2788 | IdleTimeBracketValues(void *pCounter, CARD64XSyncValue * pbracket_less, | |||
2789 | CARD64XSyncValue * pbracket_greater) | |||
2790 | { | |||
2791 | SyncCounter *counter = pCounter; | |||
2792 | IdleCounterPriv *priv = SysCounterGetPrivate(counter); | |||
2793 | XSyncValue *less = priv->value_less, | |||
2794 | *greater = priv->value_greater; | |||
2795 | Bool registered = (less || greater); | |||
2796 | ||||
2797 | if (registered && !pbracket_less && !pbracket_greater) { | |||
2798 | RemoveBlockAndWakeupHandlers(IdleTimeBlockHandler, | |||
2799 | IdleTimeWakeupHandler, pCounter); | |||
2800 | } | |||
2801 | else if (!registered && (pbracket_less || pbracket_greater)) { | |||
2802 | /* Reset flag must be zero so we don't force a idle timer reset on | |||
2803 | the first wakeup */ | |||
2804 | LastEventTimeToggleResetAll(FALSE0); | |||
2805 | RegisterBlockAndWakeupHandlers(IdleTimeBlockHandler, | |||
2806 | IdleTimeWakeupHandler, pCounter); | |||
2807 | } | |||
2808 | ||||
2809 | priv->value_greater = pbracket_greater; | |||
2810 | priv->value_less = pbracket_less; | |||
2811 | } | |||
2812 | ||||
2813 | static SyncCounter* | |||
2814 | init_system_idle_counter(const char *name, int deviceid) | |||
2815 | { | |||
2816 | CARD64XSyncValue resolution; | |||
2817 | XSyncValue idle; | |||
2818 | SyncCounter *idle_time_counter; | |||
2819 | ||||
2820 | IdleTimeQueryValue(NULL((void*)0), &idle); | |||
2821 | XSyncIntToValue(&resolution, 4)((&resolution)->hi=((4<0)?~0:0),(&resolution)-> lo=(4)); | |||
2822 | ||||
2823 | idle_time_counter = SyncCreateSystemCounter(name, idle, resolution, | |||
2824 | XSyncCounterUnrestricted, | |||
2825 | IdleTimeQueryValue, | |||
2826 | IdleTimeBracketValues); | |||
2827 | ||||
2828 | if (idle_time_counter != NULL((void*)0)) { | |||
2829 | IdleCounterPriv *priv = malloc(sizeof(IdleCounterPriv)); | |||
2830 | ||||
2831 | priv->value_less = priv->value_greater = NULL((void*)0); | |||
2832 | priv->deviceid = deviceid; | |||
2833 | ||||
2834 | idle_time_counter->pSysCounterInfo->private = priv; | |||
2835 | } | |||
2836 | ||||
2837 | return idle_time_counter; | |||
2838 | } | |||
2839 | ||||
2840 | static void | |||
2841 | SyncInitIdleTime(void) | |||
2842 | { | |||
2843 | init_system_idle_counter("IDLETIME", XIAllDevices0); | |||
2844 | } | |||
2845 | ||||
2846 | SyncCounter* | |||
2847 | SyncInitDeviceIdleTime(DeviceIntPtr dev) | |||
2848 | { | |||
2849 | char timer_name[64]; | |||
2850 | sprintf(timer_name, "DEVICEIDLETIME %d", dev->id)__builtin___sprintf_chk (timer_name, 0, __builtin_object_size (timer_name, 2 > 1 ? 1 : 0), "DEVICEIDLETIME %d", dev-> id); | |||
2851 | ||||
2852 | return init_system_idle_counter(timer_name, dev->id); | |||
2853 | } | |||
2854 | ||||
2855 | void SyncRemoveDeviceIdleTime(SyncCounter *counter) | |||
2856 | { | |||
2857 | /* FreeAllResources() frees all system counters before the devices are | |||
2858 | shut down, check if there are any left before freeing the device's | |||
2859 | counter */ | |||
2860 | if (counter && !xorg_list_is_empty(&SysCounterList)) | |||
2861 | xorg_list_del(&counter->pSysCounterInfo->entry); | |||
2862 | } |