📄 sync.c
字号:
rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; rep.priority = priorityclient->priority; if (client->swapped) { register char n; swaps(&rep.sequenceNumber, n); swapl(&rep.priority, n); } WriteToClient(client, sizeof(xSyncGetPriorityReply), (char *) &rep); return (client->noClientException);}/* * ** Create a new counter */static int ProcSyncCreateCounter(client) ClientPtr client;{ REQUEST(xSyncCreateCounterReq); CARD64 initial; REQUEST_SIZE_MATCH(xSyncCreateCounterReq); LEGAL_NEW_RESOURCE(stuff->cid, client); XSyncIntsToValue(&initial, stuff->initial_value_lo, stuff->initial_value_hi); if (!SyncCreateCounter(client, stuff->cid, initial)) return BadAlloc; return (client->noClientException);}/* * ** Set Counter value */static int ProcSyncSetCounter(client) ClientPtr client;{ REQUEST(xSyncSetCounterReq); SyncCounter *pCounter; CARD64 newvalue; pCounter = (SyncCounter *)SecurityLookupIDByType(client, stuff->cid, RTCounter, SecurityWriteAccess); if (pCounter == NULL) { client->errorValue = stuff->cid; return SyncErrorBase + XSyncBadCounter; } if (IsSystemCounter(pCounter)) { client->errorValue = stuff->cid; return BadAccess; } XSyncIntsToValue(&newvalue, stuff->value_lo, stuff->value_hi); SyncChangeCounter(pCounter, newvalue); return Success;}/* * ** Change Counter value */static int ProcSyncChangeCounter(client) ClientPtr client;{ REQUEST(xSyncChangeCounterReq); SyncCounter *pCounter; CARD64 newvalue; Bool overflow; REQUEST_SIZE_MATCH(xSyncChangeCounterReq); pCounter = (SyncCounter *) SecurityLookupIDByType(client, stuff->cid, RTCounter, SecurityWriteAccess); if (pCounter == NULL) { client->errorValue = stuff->cid; return SyncErrorBase + XSyncBadCounter; } if (IsSystemCounter(pCounter)) { client->errorValue = stuff->cid; return BadAccess; } XSyncIntsToValue(&newvalue, stuff->value_lo, stuff->value_hi); XSyncValueAdd(&newvalue, pCounter->value, newvalue, &overflow); if (overflow) { /* XXX 64 bit value can't fit in 32 bits; do the best we can */ client->errorValue = stuff->value_hi; return BadValue; } SyncChangeCounter(pCounter, newvalue); return Success;}/* * ** Destroy a counter */static int ProcSyncDestroyCounter(client) ClientPtr client;{ REQUEST(xSyncDestroyCounterReq); SyncCounter *pCounter; REQUEST_SIZE_MATCH(xSyncDestroyCounterReq); pCounter = (SyncCounter *)SecurityLookupIDByType(client, stuff->counter, RTCounter, SecurityDestroyAccess); if (pCounter == NULL) { client->errorValue = stuff->counter; return SyncErrorBase + XSyncBadCounter; } if (IsSystemCounter(pCounter)) { client->errorValue = stuff->counter; return BadAccess; } FreeResource(pCounter->id, RT_NONE); return Success;}/* * ** Await */static int ProcSyncAwait(client) ClientPtr client;{ REQUEST(xSyncAwaitReq); int len, items; int i; xSyncWaitCondition *pProtocolWaitConds; SyncAwaitUnion *pAwaitUnion; SyncAwait *pAwait; int status; REQUEST_AT_LEAST_SIZE(xSyncAwaitReq); len = client->req_len << 2; len -= sz_xSyncAwaitReq; items = len / sz_xSyncWaitCondition; if (items * sz_xSyncWaitCondition != len) { return BadLength; } if (items == 0) { client->errorValue = items; /* XXX protocol change */ return BadValue; } pProtocolWaitConds = (xSyncWaitCondition *) & stuff[1]; /* all the memory for the entire await list is allocated * here in one chunk */ pAwaitUnion = (SyncAwaitUnion *)xalloc((items+1) * sizeof(SyncAwaitUnion)); if (!pAwaitUnion) return BadAlloc; /* first item is the header, remainder are real wait conditions */ pAwaitUnion->header.delete_id = FakeClientID(client->index); if (!AddResource(pAwaitUnion->header.delete_id, RTAwait, pAwaitUnion)) { xfree(pAwaitUnion); return BadAlloc; } /* don't need to do any more memory allocation for this request! */ pAwaitUnion->header.client = client; pAwaitUnion->header.num_waitconditions = 0; pAwait = &(pAwaitUnion+1)->await; /* skip over header */ for (i = 0; i < items; i++, pProtocolWaitConds++, pAwait++) { if (pProtocolWaitConds->counter == None) /* XXX protocol change */ { /* this should take care of removing any triggers created by * this request that have already been registered on counters */ FreeResource(pAwaitUnion->header.delete_id, RT_NONE); client->errorValue = pProtocolWaitConds->counter; return SyncErrorBase + XSyncBadCounter; } /* sanity checks are in SyncInitTrigger */ pAwait->trigger.pCounter = NULL; pAwait->trigger.value_type = pProtocolWaitConds->value_type; XSyncIntsToValue(&pAwait->trigger.wait_value, pProtocolWaitConds->wait_value_lo, pProtocolWaitConds->wait_value_hi); pAwait->trigger.test_type = pProtocolWaitConds->test_type; status = SyncInitTrigger(client, &pAwait->trigger, pProtocolWaitConds->counter, XSyncCAAllTrigger); if (status != Success) { /* this should take care of removing any triggers created by * this request that have already been registered on counters */ FreeResource(pAwaitUnion->header.delete_id, RT_NONE); return status; } /* this is not a mistake -- same function works for both cases */ pAwait->trigger.TriggerFired = SyncAwaitTriggerFired; pAwait->trigger.CounterDestroyed = SyncAwaitTriggerFired; XSyncIntsToValue(&pAwait->event_threshold, pProtocolWaitConds->event_threshold_lo, pProtocolWaitConds->event_threshold_hi); pAwait->pHeader = &pAwaitUnion->header; pAwaitUnion->header.num_waitconditions++; } IgnoreClient(client); /* see if any of the triggers are already true */ pAwait = &(pAwaitUnion+1)->await; /* skip over header */ for (i = 0; i < items; i++, pAwait++) { /* don't have to worry about NULL counters because the request * errors before we get here out if they occur */ if ((*pAwait->trigger.CheckTrigger)(&pAwait->trigger, pAwait->trigger.pCounter->value)) { (*pAwait->trigger.TriggerFired)(&pAwait->trigger); break; /* once is enough */ } } return Success;}/* * ** Query a counter */static int ProcSyncQueryCounter(client) ClientPtr client;{ REQUEST(xSyncQueryCounterReq); xSyncQueryCounterReply rep; SyncCounter *pCounter; REQUEST_SIZE_MATCH(xSyncQueryCounterReq); pCounter = (SyncCounter *)SecurityLookupIDByType(client, stuff->counter, RTCounter, SecurityReadAccess); if (pCounter == NULL) { client->errorValue = stuff->counter; return SyncErrorBase + XSyncBadCounter; } rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; /* if system counter, ask it what the current value is */ if (IsSystemCounter(pCounter)) { (*pCounter->pSysCounterInfo->QueryValue) ((pointer) pCounter, &pCounter->value); } rep.value_hi = XSyncValueHigh32(pCounter->value); rep.value_lo = XSyncValueLow32(pCounter->value); if (client->swapped) { register char n; swaps(&rep.sequenceNumber, n); swapl(&rep.length, n); swapl(&rep.value_hi, n); swapl(&rep.value_lo, n); } WriteToClient(client, sizeof(xSyncQueryCounterReply), (char *) &rep); return (client->noClientException);}/* * ** Create Alarm */static int ProcSyncCreateAlarm(client) ClientPtr client;{ REQUEST(xSyncCreateAlarmReq); SyncAlarm *pAlarm; int status; unsigned long len, vmask; SyncTrigger *pTrigger; REQUEST_AT_LEAST_SIZE(xSyncCreateAlarmReq); LEGAL_NEW_RESOURCE(stuff->id, client); vmask = stuff->valueMask; len = client->req_len - (sizeof(xSyncCreateAlarmReq) >> 2); /* the "extra" call to Ones accounts for the presence of 64 bit values */ if (len != (Ones(vmask) + Ones(vmask & (XSyncCAValue|XSyncCADelta)))) return BadLength; if (!(pAlarm = (SyncAlarm *) xalloc(sizeof(SyncAlarm)))) { return BadAlloc; } /* set up defaults */ pTrigger = &pAlarm->trigger; pTrigger->pCounter = NULL; pTrigger->value_type = XSyncAbsolute; XSyncIntToValue(&pTrigger->wait_value, 0L); pTrigger->test_type = XSyncPositiveComparison; pTrigger->TriggerFired = SyncAlarmTriggerFired; pTrigger->CounterDestroyed = SyncAlarmCounterDestroyed; status = SyncInitTrigger(client, pTrigger, None, XSyncCAAllTrigger); if (status != Success) { xfree(pAlarm); return status; } pAlarm->client = client; pAlarm->alarm_id = stuff->id; XSyncIntToValue(&pAlarm->delta, 1L); pAlarm->events = TRUE; pAlarm->state = XSyncAlarmInactive; pAlarm->pEventClients = NULL; status = SyncChangeAlarmAttributes(client, pAlarm, vmask, (CARD32 *)&stuff[1]); if (status != Success) { xfree(pAlarm); return status; } if (!AddResource(stuff->id, RTAlarm, pAlarm)) { xfree(pAlarm); return BadAlloc; } /* see if alarm already triggered. NULL counter will not trigger * in CreateAlarm and sets alarm state to Inactive. */ if (!pTrigger->pCounter) { pAlarm->state = XSyncAlarmInactive; /* XXX protocol change */ } else if ((*pTrigger->CheckTrigger)(pTrigger, pTrigger->pCounter->value)) { (*pTrigger->TriggerFired)(pTrigger); } return Success;}/* * ** Change Alarm */static int ProcSyncChangeAlarm(client) ClientPtr client;{ REQUEST(xSyncChangeAlarmReq); SyncAlarm *pAlarm; long vmask; int len, status; REQUEST_AT_LEAST_SIZE(xSyncChangeAlarmReq); if (!(pAlarm = (SyncAlarm *)SecurityLookupIDByType(client, stuff->alarm, RTAlarm, SecurityWriteAccess))) { client->errorValue = stuff->alarm; return SyncErrorBase + XSyncBadAlarm; } vmask = stuff->valueMask; len = client->req_len - (sizeof(xSyncChangeAlarmReq) >> 2); /* the "extra" call to Ones accounts for the presence of 64 bit values */ if (len != (Ones(vmask) + Ones(vmask & (XSyncCAValue|XSyncCADelta)))) return BadLength; if ((status = SyncChangeAlarmAttributes(client, pAlarm, vmask, (CARD32 *)&stuff[1])) != Success) return status; /* see if alarm already triggered. NULL counter WILL trigger * in ChangeAlarm. */ if (!pAlarm->trigger.pCounter || (*pAlarm->trigger.CheckTrigger)(&pAlarm->trigger, pAlarm->trigger.pCounter->value)) { (*pAlarm->trigger.TriggerFired)(&pAlarm->trigger); } return Success;}static int ProcSyncQueryAlarm(client) ClientPtr client;{ REQUEST(xSyncQueryAlarmReq); SyncAlarm *pAlarm; xSyncQueryAlarmReply rep; SyncTrigger *pTrigger; REQUEST_SIZE_MATCH(xSyncQueryAlarmReq); pAlarm = (SyncAlarm *)SecurityLookupIDByType(client, stuff->alarm, RTAlarm, SecurityReadAccess); if (!pAlarm) { client->errorValue = stuff->alarm; return (SyncErrorBase + XSyncBadAlarm); } rep.type = X_Reply; rep.length = (sizeof(xSyncQueryAlarmReply) - sizeof(xGenericReply)) >> 2; rep.sequenceNumber = client->sequence; pTrigger = &pAlarm->trigger; rep.counter = (pTrigger->pCounter) ? pTrigger->pCounter->id : None;#if 0 /* XXX unclear what to do, depends on whether relative value-types * are "consumed" immediately and are considered absolute from then * on. */ rep.value_type = pTrigger->value_type; rep.wait_value_hi = XSyncValueHigh32(pTrigger->wait_value); rep.wait_value_lo = XSyncValueLow32(pTrigger->wait_value);#else rep.value_type = XSyncAbsolute; rep.wait_value_hi = XSyncValueHigh32(pTrigger->test_value); rep.wait_value_lo = XSyncValueLow32(pTrigger->test_value);#endif rep.test_type = pTrigger->test_type; rep.delta_hi = XSyncValueHigh32(pAlarm->delta); rep.delta_lo = XSyncValueLow32(pAlarm->delta); rep.events = pAlarm->events; rep.state = pAlarm->state; if (client->swapped) { register char n; swaps(&rep.sequenceNumber, n); swapl(&rep.length, n); swapl(&rep.counter, n); swapl(&rep.wait_value_hi, n); swapl(&rep.wait_value_lo, n); swapl(&rep.test_type, n); swapl(&rep.delta_hi, n); swapl(&rep.delta_lo, n); } WriteToClient(client, sizeof(xSyncQueryAlarmReply), (char *) &rep); return (client->noClientException);}static int ProcSyncDestroyAlarm(client) ClientPtr client;{ SyncAlarm *pAlarm; REQUEST(xSyncDestroyAlarmReq); REQUEST_SIZE_MATCH(xSyncDestroyAlarmReq); if (!(pAlarm = (SyncAlarm *)SecurityLookupIDByType(client, stuff->alarm, RTAlarm, SecurityDestroyAccess))) { client->errorValue = stuff->alarm; return SyncErrorBase + XSyncBadAlarm; } FreeResource(stuff->alarm, RT_NONE); return (client->noClientException);}/* * ** Given an extension request, call the appropriate request procedure */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -