📄 sync.c
字号:
if (origmask & (XSyncCADelta|XSyncCATestType)) { CARD64 zero; XSyncIntToValue(&zero, 0); if ((((pAlarm->trigger.test_type == XSyncPositiveComparison) || (pAlarm->trigger.test_type == XSyncPositiveTransition)) && XSyncValueLessThan(pAlarm->delta, zero)) || (((pAlarm->trigger.test_type == XSyncNegativeComparison) || (pAlarm->trigger.test_type == XSyncNegativeTransition)) && XSyncValueGreaterThan(pAlarm->delta, zero)) ) { return BadMatch; } } /* postpone this until now, when we're sure nothing else can go wrong */ if ((status = SyncInitTrigger(client, &pAlarm->trigger, counter, origmask & XSyncCAAllTrigger)) != Success) return status; /* XXX spec does not really say to do this - needs clarification */ pAlarm->state = XSyncAlarmActive; return Success;}static SyncCounter *SyncCreateCounter(client, id, initialvalue) ClientPtr client; XSyncCounter id; CARD64 initialvalue;{ SyncCounter *pCounter; if (!(pCounter = (SyncCounter *) xalloc(sizeof(SyncCounter)))) return (SyncCounter *)NULL; if (!AddResource(id, RTCounter, (pointer) pCounter)) { xfree((pointer) pCounter); return (SyncCounter *)NULL; } pCounter->client = client; pCounter->id = id; pCounter->value = initialvalue; pCounter->pTriglist = NULL; pCounter->beingDestroyed = FALSE; pCounter->pSysCounterInfo = NULL; return pCounter;}static int FreeCounter(#if NeedFunctionPrototypes pointer /*env*/, XID /*id*/#endif);/* * ***** System Counter utilities */pointer SyncCreateSystemCounter(name, initial, resolution, counterType, QueryValue, BracketValues) char *name; CARD64 initial; CARD64 resolution; SyncCounterType counterType; void (*QueryValue) (); void (*BracketValues) ();{ SyncCounter *pCounter; SysCounterList = (SyncCounter **)xrealloc(SysCounterList, (SyncNumSystemCounters+1)*sizeof(SyncCounter *)); if (!SysCounterList) return (pointer)NULL; /* this function may be called before SYNC has been initialized, so we * have to make sure RTCounter is created. */ if (RTCounter == 0) { RTCounter = CreateNewResourceType(FreeCounter); if (RTCounter == 0) { return (pointer)NULL; } } pCounter = SyncCreateCounter((ClientPtr)NULL, FakeClientID(0), initial); if (pCounter) { SysCounterInfo *psci; psci = (SysCounterInfo *)xalloc(sizeof(SysCounterInfo)); if (!psci) { FreeResource(pCounter->id, RT_NONE); return (pointer) pCounter; } pCounter->pSysCounterInfo = psci; psci->name = name; psci->resolution = resolution; psci->counterType = counterType; psci->QueryValue = QueryValue; psci->BracketValues = BracketValues; XSyncMaxValue(&psci->bracket_greater); XSyncMinValue(&psci->bracket_less); SysCounterList[SyncNumSystemCounters++] = pCounter; } return (pointer) pCounter;}voidSyncDestroySystemCounter(pSysCounter) pointer pSysCounter;{ SyncCounter *pCounter = (SyncCounter *)pSysCounter; FreeResource(pCounter->id, RT_NONE);}static voidSyncComputeBracketValues(pCounter, startOver) SyncCounter *pCounter; Bool startOver;{ SyncTriggerList *pCur; SyncTrigger *pTrigger; SysCounterInfo *psci = pCounter->pSysCounterInfo; CARD64 *pnewgtval = NULL; CARD64 *pnewltval = NULL; SyncCounterType ct; if (!pCounter) return; ct = pCounter->pSysCounterInfo->counterType; if (ct == XSyncCounterNeverChanges) return; if (startOver) { XSyncMaxValue(&psci->bracket_greater); XSyncMinValue(&psci->bracket_less); } for (pCur = pCounter->pTriglist; pCur; pCur = pCur->next) { pTrigger = pCur->pTrigger; if (pTrigger->test_type == XSyncPositiveComparison && ct != XSyncCounterNeverIncreases) { if (XSyncValueLessThan(pCounter->value, pTrigger->test_value) && XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater)) { psci->bracket_greater = pTrigger->test_value; pnewgtval = &psci->bracket_greater; } } else if (pTrigger->test_type == XSyncNegativeComparison && ct != XSyncCounterNeverDecreases) { if (XSyncValueGreaterThan(pCounter->value, pTrigger->test_value) && XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less)) { psci->bracket_less = pTrigger->test_value; pnewltval = &psci->bracket_less; } } else if ( (pTrigger->test_type == XSyncPositiveTransition && ct != XSyncCounterNeverIncreases) || (pTrigger->test_type == XSyncNegativeTransition && ct != XSyncCounterNeverDecreases) ) { if (XSyncValueLessThan(pCounter->value, pTrigger->test_value)) { if (XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater)) { psci->bracket_greater = pTrigger->test_value; pnewgtval = &psci->bracket_greater; } else if (XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less)) { psci->bracket_less = pTrigger->test_value; pnewltval = &psci->bracket_less; } } } } /* end for each trigger */ if (pnewgtval || pnewltval) { (*psci->BracketValues)((pointer)pCounter, pnewltval, pnewgtval); }}/* * ***** Resource delete functions *//* ARGSUSED */static intFreeAlarm(addr, id) pointer addr; XID id;{ SyncAlarm *pAlarm = (SyncAlarm *) addr; pAlarm->state = XSyncAlarmDestroyed; SyncSendAlarmNotifyEvents(pAlarm); /* delete event selections */ while (pAlarm->pEventClients) FreeResource(pAlarm->pEventClients->delete_id, RT_NONE); SyncDeleteTriggerFromCounter(&pAlarm->trigger); xfree(pAlarm); return Success;}/* * ** Cleanup after the destruction of a Counter *//* ARGSUSED */static intFreeCounter(env, id) pointer env; XID id;{ SyncCounter *pCounter = (SyncCounter *) env; SyncTriggerList *ptl, *pnext; pCounter->beingDestroyed = TRUE; /* tell all the counter's triggers that the counter has been destroyed */ for (ptl = pCounter->pTriglist; ptl; ptl = pnext) { (*ptl->pTrigger->CounterDestroyed)(ptl->pTrigger); pnext = ptl->next; xfree(ptl); /* destroy the trigger list as we go */ } if (IsSystemCounter(pCounter)) { int i, found = 0; xfree(pCounter->pSysCounterInfo); /* find the counter in the list of system counters and remove it */ if (SysCounterList) { for (i = 0; i < SyncNumSystemCounters; i++) { if (SysCounterList[i] == pCounter) { found = i; break; } } if (found < (SyncNumSystemCounters-1)) { for (i = found; i < SyncNumSystemCounters-1; i++) { SysCounterList[i] = SysCounterList[i+1]; } } } SyncNumSystemCounters--; } xfree(pCounter); return Success;}/* * ** Cleanup after Await *//* ARGSUSED */static intFreeAwait(addr, id) pointer addr; XID id;{ SyncAwaitUnion *pAwaitUnion = (SyncAwaitUnion *) addr; SyncAwait *pAwait; int numwaits; pAwait = &(pAwaitUnion+1)->await; /* first await on list */ /* remove triggers from counters */ for (numwaits = pAwaitUnion->header.num_waitconditions; numwaits; numwaits--, pAwait++) { /* If the counter is being destroyed, FreeCounter will delete * the trigger list itself, so don't do it here. */ SyncCounter *pCounter = pAwait->trigger.pCounter; if (pCounter && !pCounter->beingDestroyed) SyncDeleteTriggerFromCounter(&pAwait->trigger); } xfree(pAwaitUnion); return Success;}/* loosely based on dix/events.c/OtherClientGone */static intFreeAlarmClient(value, id) pointer value; /* must conform to DeleteType */ XID id;{ SyncAlarm *pAlarm = (SyncAlarm *)value; SyncAlarmClientList *pCur, *pPrev; for (pPrev = NULL, pCur = pAlarm->pEventClients; pCur; pPrev = pCur, pCur = pCur->next) { if (pCur->delete_id == id) { if (pPrev) pPrev->next = pCur->next; else pAlarm->pEventClients = pCur->next; xfree(pCur); return(Success); } } FatalError("alarm client not on event list"); /*NOTREACHED*/}/* * ***** Proc functions *//* * ** Initialize the extension */static int ProcSyncInitialize(client) ClientPtr client;{ xSyncInitializeReply rep; int n; REQUEST_SIZE_MATCH(xSyncInitializeReq); rep.type = X_Reply; rep.sequenceNumber = client->sequence; rep.majorVersion = SYNC_MAJOR_VERSION; rep.minorVersion = SYNC_MINOR_VERSION; rep.length = 0; if (client->swapped) { swaps(&rep.sequenceNumber, n); } WriteToClient(client, sizeof(rep), (char *) &rep); return (client->noClientException);}/* * ** Get list of system counters available through the extension */static int ProcSyncListSystemCounters(client) ClientPtr client;{ xSyncListSystemCountersReply rep; int i, len; xSyncSystemCounter *list, *walklist; REQUEST_SIZE_MATCH(xSyncListSystemCountersReq); rep.type = X_Reply; rep.sequenceNumber = client->sequence; rep.nCounters = SyncNumSystemCounters; for (i = len = 0; i < SyncNumSystemCounters; i++) { char *name = SysCounterList[i]->pSysCounterInfo->name; /* pad to 4 byte boundary */ len += (sz_xSyncSystemCounter + strlen(name) + 3) & ~3; } if (len) { walklist = list = (xSyncSystemCounter *) ALLOCATE_LOCAL(len); if (!list) return BadAlloc; } rep.length = len >> 2; if (client->swapped) { register char n; swaps(&rep.sequenceNumber, n); swapl(&rep.length, n); swapl(&rep.nCounters, n); } for (i = 0; i < SyncNumSystemCounters; i++) { int namelen; char *pname_in_reply; SysCounterInfo *psci = SysCounterList[i]->pSysCounterInfo; walklist->counter = SysCounterList[i]->id; walklist->resolution_hi = XSyncValueHigh32(psci->resolution); walklist->resolution_lo = XSyncValueLow32(psci->resolution); namelen = strlen(psci->name); walklist->name_length = namelen; if (client->swapped) { register char n; swapl(&walklist->counter, n); swapl(&walklist->resolution_hi, n); swapl(&walklist->resolution_lo, n); swaps(&walklist->name_length, n); } pname_in_reply = ((char *)walklist) + sz_xSyncSystemCounter; strncpy(pname_in_reply, psci->name, namelen); walklist = (xSyncSystemCounter *) (((char *)walklist) + ((sz_xSyncSystemCounter + namelen + 3) & ~3)); } WriteToClient(client, sizeof(rep), (char *) &rep); if (len) { WriteToClient(client, len, (char *) list); DEALLOCATE_LOCAL(list); } return (client->noClientException);}/* * ** Set client Priority */static int ProcSyncSetPriority(client) ClientPtr client;{ REQUEST(xSyncSetPriorityReq); ClientPtr priorityclient; REQUEST_SIZE_MATCH(xSyncSetPriorityReq); if (stuff->id == None) priorityclient = client; else if (!(priorityclient = LookupClient(stuff->id, client))) { client->errorValue = stuff->id; return BadMatch; } if (priorityclient->priority != stuff->priority) { priorityclient->priority = stuff->priority; /* The following will force the server back into WaitForSomething * so that the change in this client's priority is immediately * reflected. */ isItTimeToYield = TRUE; dispatchException |= DE_PRIORITYCHANGE; } return Success;}/* * ** Get client Priority */static int ProcSyncGetPriority(client) ClientPtr client;{ REQUEST(xSyncGetPriorityReq); xSyncGetPriorityReply rep; ClientPtr priorityclient; REQUEST_SIZE_MATCH(xSyncGetPriorityReq); if (stuff->id == None) priorityclient = client; else if (!(priorityclient = LookupClient(stuff->id, client))) { client->errorValue = stuff->id; return BadMatch; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -