⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sync.c

📁 远程桌面连接工具
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (pTrigger->test_type != XSyncPositiveTransition &&	    pTrigger->test_type != XSyncNegativeTransition &&	    pTrigger->test_type != XSyncPositiveComparison &&	    pTrigger->test_type != XSyncNegativeComparison)	{	    client->errorValue = pTrigger->test_type;	    return BadValue;	}	/* select appropriate CheckTrigger function */	switch (pTrigger->test_type)	{        case XSyncPositiveTransition: 	    pTrigger->CheckTrigger = SyncCheckTriggerPositiveTransition;	    break;        case XSyncNegativeTransition: 	    pTrigger->CheckTrigger = SyncCheckTriggerNegativeTransition;	    break;        case XSyncPositiveComparison: 	    pTrigger->CheckTrigger = SyncCheckTriggerPositiveComparison;	    break;        case XSyncNegativeComparison: 	    pTrigger->CheckTrigger = SyncCheckTriggerNegativeComparison;	    break;	}    }    if (changes & (XSyncCAValueType | XSyncCAValue))    {	if (pTrigger->value_type == XSyncAbsolute)	    pTrigger->test_value = pTrigger->wait_value;	else /* relative */	{	    Bool overflow;	    if (pCounter == NULL)		return BadMatch;	    XSyncValueAdd(&pTrigger->test_value, pCounter->value, 			  pTrigger->wait_value, &overflow);	    if (overflow)	    {		client->errorValue = XSyncValueHigh32(pTrigger->wait_value);		return BadValue;	    }	}    }    /*  we wait until we're sure there are no errors before registering     *  a new counter on a trigger     */    if (newcounter)    {	if ((status = SyncAddTriggerToCounter(pTrigger)) != Success)	    return status;    }    else if (IsSystemCounter(pCounter))    {	SyncComputeBracketValues(pCounter, /*startOver*/ TRUE);    }        return Success;}/*  AlarmNotify events happen in response to actions taken on an Alarm or *  the counter used by the alarm.  AlarmNotify may be sent to multiple  *  clients.  The alarm maintains a list of clients interested in events. */static voidSyncSendAlarmNotifyEvents(pAlarm)    SyncAlarm *pAlarm;{    SyncAlarmClientList *pcl;    xSyncAlarmNotifyEvent ane;    SyncTrigger *pTrigger = &pAlarm->trigger;    UpdateCurrentTime();    ane.type = SyncEventBase + XSyncAlarmNotify;    ane.kind = XSyncAlarmNotify;    ane.sequenceNumber = pAlarm->client->sequence;    ane.alarm = pAlarm->alarm_id;    if (pTrigger->pCounter)    {	ane.counter_value_hi = XSyncValueHigh32(pTrigger->pCounter->value);	ane.counter_value_lo = XSyncValueLow32(pTrigger->pCounter->value);    }    else    { /* XXX what else can we do if there's no counter? */	ane.counter_value_hi = ane.counter_value_lo = 0;    }    ane.alarm_value_hi = XSyncValueHigh32(pTrigger->test_value);    ane.alarm_value_lo = XSyncValueLow32(pTrigger->test_value);    ane.time = currentTime.milliseconds;    ane.state = pAlarm->state;    /* send to owner */    if (pAlarm->events && !pAlarm->client->clientGone) 	WriteEventsToClient(pAlarm->client, 1, (xEvent *) &ane);    /* send to other interested clients */    for (pcl = pAlarm->pEventClients; pcl; pcl = pcl->next)    {	if (!pAlarm->client->clientGone)	{	    ane.sequenceNumber = pcl->client->sequence;	    WriteEventsToClient(pcl->client, 1, (xEvent *) &ane);	}    }}/*  CounterNotify events only occur in response to an Await.  The events  *  go only to the Awaiting client. */static voidSyncSendCounterNotifyEvents(client, ppAwait, num_events)    ClientPtr client;    SyncAwait **ppAwait;    int num_events;{    xSyncCounterNotifyEvent *pEvents, *pev;    int i;    if (client->clientGone)	return;    pev = pEvents = (xSyncCounterNotifyEvent *)		 ALLOCATE_LOCAL(num_events * sizeof(xSyncCounterNotifyEvent));    if (!pEvents) 	return;    UpdateCurrentTime();    for (i = 0; i < num_events; i++, ppAwait++, pev++)    {	SyncTrigger *pTrigger = &(*ppAwait)->trigger;	pev->type = SyncEventBase + XSyncCounterNotify;	pev->kind = XSyncCounterNotify;	pev->sequenceNumber = client->sequence;	pev->counter = pTrigger->pCounter->id;	pev->wait_value_lo = XSyncValueLow32(pTrigger->test_value);	pev->wait_value_hi = XSyncValueHigh32(pTrigger->test_value);	pev->counter_value_lo = XSyncValueLow32(pTrigger->pCounter->value);	pev->counter_value_hi = XSyncValueHigh32(pTrigger->pCounter->value);	pev->time = currentTime.milliseconds;	pev->count = num_events - i - 1; /* events remaining */	pev->destroyed = pTrigger->pCounter->beingDestroyed;    }    /* swapping will be taken care of by this */    WriteEventsToClient(client, num_events, (xEvent *)pEvents);    DEALLOCATE_LOCAL(pEvents);}/* This function is called when an alarm's counter is destroyed. * It is plugged into pTrigger->CounterDestroyed (for alarm triggers). */voidSyncAlarmCounterDestroyed(pTrigger)    SyncTrigger *pTrigger;{    SyncAlarm *pAlarm = (SyncAlarm *)pTrigger;    pAlarm->state = XSyncAlarmInactive;    SyncSendAlarmNotifyEvents(pAlarm);    pTrigger->pCounter = NULL;}/*  This function is called when an alarm "goes off."   *  It is plugged into pTrigger->TriggerFired (for alarm triggers). */static voidSyncAlarmTriggerFired(pTrigger)    SyncTrigger *pTrigger;{    SyncAlarm *pAlarm = (SyncAlarm *)pTrigger;    CARD64 new_test_value;    /* no need to check alarm unless it's active */    if (pAlarm->state != XSyncAlarmActive)	return;    /*  " if the counter value is None, or if the delta is 0 and     *    the test-type is PositiveComparison or NegativeComparison,     *    no change is made to value (test-value) and the alarm     *    state is changed to Inactive before the event is generated."     */    if (pAlarm->trigger.pCounter == NULL	|| (XSyncValueIsZero(pAlarm->delta)	    && (pAlarm->trigger.test_type == XSyncPositiveComparison		|| pAlarm->trigger.test_type == XSyncNegativeComparison)))	pAlarm->state = XSyncAlarmInactive;    new_test_value = pAlarm->trigger.test_value;    if (pAlarm->state == XSyncAlarmActive)    {	Bool overflow;	CARD64 oldvalue;	SyncTrigger *paTrigger = &pAlarm->trigger;	/* "The alarm is updated by repeatedly adding delta to the	 *  value of the trigger and re-initializing it until it	 *  becomes FALSE."	 */	oldvalue = paTrigger->test_value;	/* XXX really should do something smarter here */	do	{	    XSyncValueAdd(&paTrigger->test_value, paTrigger->test_value,			  pAlarm->delta, &overflow);	} while (!overflow && 	      (*paTrigger->CheckTrigger)(paTrigger,					paTrigger->pCounter->value));	new_test_value = paTrigger->test_value;	paTrigger->test_value = oldvalue;	/* "If this update would cause value to fall outside the range	 *  for an INT64...no change is made to value (test-value) and	 *  the alarm state is changed to Inactive before the event is	 *  generated."	 */	if (overflow)	{	    new_test_value = oldvalue;	    pAlarm->state = XSyncAlarmInactive;	}    }    /*  The AlarmNotify event has to have the "new state of the alarm"     *  which we can't be sure of until this point.  However, it has     *  to have the "old" trigger test value.  That's the reason for     *  all the newvalue/oldvalue shuffling above.  After we send the     *  events, give the trigger its new test value.     */    SyncSendAlarmNotifyEvents(pAlarm);    pTrigger->test_value = new_test_value;}/*  This function is called when an Await unblocks, either as a result *  of the trigger firing OR the counter being destroyed. *  It goes into pTrigger->TriggerFired AND pTrigger->CounterDestroyed *  (for Await triggers). */static voidSyncAwaitTriggerFired(pTrigger)    SyncTrigger *pTrigger;{    SyncAwait *pAwait = (SyncAwait *)pTrigger;    int numwaits;    SyncAwaitUnion *pAwaitUnion;    SyncAwait **ppAwait;    int num_events = 0;    pAwaitUnion = (SyncAwaitUnion *)pAwait->pHeader;    numwaits = pAwaitUnion->header.num_waitconditions;    ppAwait = (SyncAwait **)ALLOCATE_LOCAL(numwaits * sizeof(SyncAwait *));    if (!ppAwait)	goto bail;    pAwait = &(pAwaitUnion+1)->await;    /* "When a client is unblocked, all the CounterNotify events for     *  the Await request are generated contiguously. If count is 0     *  there are no more events to follow for this request. If     *  count is n, there are at least n more events to follow."     *     *  Thus, it is best to find all the counters for which events     *  need to be sent first, so that an accurate count field can     *  be stored in the events.     */    for ( ; numwaits; numwaits--, pAwait++)    {	CARD64 diff;	Bool overflow, diffgreater, diffequal;	/* "A CounterNotify event with the destroyed flag set to TRUE is	 *  always generated if the counter for one of the triggers is	 *  destroyed."	 */	if (pAwait->trigger.pCounter->beingDestroyed)	{	    ppAwait[num_events++] = pAwait;	    continue;	}	/* "The difference between the counter and the test value is	 *  calculated by subtracting the test value from the value of	 *  the counter."	 */	XSyncValueSubtract(&diff, pAwait->trigger.pCounter->value,			   pAwait->trigger.test_value, &overflow);	/* "If the difference lies outside the range for an INT64, an	 *  event is not generated."	 */	if (overflow)	    continue;	diffgreater = XSyncValueGreaterThan(diff, pAwait->event_threshold);	diffequal   = XSyncValueEqual(diff, pAwait->event_threshold);	/* "If the test-type is PositiveTransition or	 *  PositiveComparison, a CounterNotify event is generated if	 *  the difference is at least event-threshold. If the test-type	 *  is NegativeTransition or NegativeComparison, a CounterNotify	 *  event is generated if the difference is at most	 *  event-threshold."	 */	if ( ((pAwait->trigger.test_type == XSyncPositiveComparison ||	       pAwait->trigger.test_type == XSyncPositiveTransition)	       && (diffgreater || diffequal))	     ||	     ((pAwait->trigger.test_type == XSyncNegativeComparison ||	       pAwait->trigger.test_type == XSyncNegativeTransition)	      && (!diffgreater) /* less or equal */	      )	   )	{	    ppAwait[num_events++] = pAwait;	}    }    if (num_events)	SyncSendCounterNotifyEvents(pAwaitUnion->header.client, ppAwait,				    num_events);    DEALLOCATE_LOCAL(ppAwait);bail:    /* unblock the client */    AttendClient(pAwaitUnion->header.client);    /* delete the await */    FreeResource(pAwaitUnion->header.delete_id, RT_NONE);}/*  This function should always be used to change a counter's value so that *  any triggers depending on the counter will be checked. */voidSyncChangeCounter(pCounter, newval)    SyncCounter    *pCounter;    CARD64         newval;{    SyncTriggerList       *ptl, *pnext;    CARD64 oldval;    oldval = pCounter->value;    pCounter->value = newval;    /* run through triggers to see if any become true */    for (ptl = pCounter->pTriglist; ptl; ptl = pnext)    {	pnext = ptl->next;	if ((*ptl->pTrigger->CheckTrigger)(ptl->pTrigger, oldval))	    (*ptl->pTrigger->TriggerFired)(ptl->pTrigger);    }    if (IsSystemCounter(pCounter))    {	SyncComputeBracketValues(pCounter, /* startOver */ FALSE);    }}/* loosely based on dix/events.c/EventSelectForWindow */static BoolSyncEventSelectForAlarm(pAlarm, client, wantevents)    SyncAlarm *pAlarm;    ClientPtr client;    Bool      wantevents;{    SyncAlarmClientList *pClients;    if (client == pAlarm->client) /* alarm owner */    {	pAlarm->events = wantevents;	return Success;    }    /* see if the client is already on the list (has events selected) */    for (pClients = pAlarm->pEventClients; pClients;	 pClients = pClients->next)    {	if (pClients->client == client)	{	    /* client's presence on the list indicates desire for 	     * events.  If the client doesn't want events, remove it 	     * from the list.  If the client does want events, do	     * nothing, since it's already got them.	     */	    if (!wantevents)	    {		FreeResource(pClients->delete_id, RT_NONE);	    }	    return Success;	}    }    /*  if we get here, this client does not currently have     *  events selected on the alarm     */    if (!wantevents)	/* client doesn't want events, and we just discovered that it 	 * doesn't have them, so there's nothing to do.	 */	return Success;    /* add new client to pAlarm->pEventClients */    pClients = (SyncAlarmClientList *) xalloc(sizeof(SyncAlarmClientList));    if (!pClients)	return BadAlloc;    /*  register it as a resource so it will be cleaned up      *  if the client dies     */    pClients->delete_id = FakeClientID(client->index);    if (!AddResource(pClients->delete_id, RTAlarmClient, pAlarm))    {	xfree(pClients);	return BadAlloc;    }    /* link it into list after we know all the allocations succeed */    pClients->next = pAlarm->pEventClients;    pAlarm->pEventClients = pClients;    pClients->client = client;    return Success;}/* * ** SyncChangeAlarmAttributes ** This is used by CreateAlarm and ChangeAlarm */static int SyncChangeAlarmAttributes(client, pAlarm, mask, values)    ClientPtr       client;    SyncAlarm      *pAlarm;    Mask	    mask;    CARD32	    *values;{    int		   status;    XSyncCounter   counter;    Mask	   origmask = mask;    counter = pAlarm->trigger.pCounter ? pAlarm->trigger.pCounter->id : None;    while (mask)    {	int    index2 = lowbit(mask);	mask &= ~index2;	switch (index2)	{	  case XSyncCACounter:	    mask &= ~XSyncCACounter;	    /* sanity check in SyncInitTrigger */	    counter = *values++;	    break;	  case XSyncCAValueType:	    mask &= ~XSyncCAValueType;	    /* sanity check in SyncInitTrigger */	    pAlarm->trigger.value_type = *values++;	    break;	  case XSyncCAValue:	    mask &= ~XSyncCAValue;	    XSyncIntsToValue(&pAlarm->trigger.wait_value, values[1], values[0]);	    values += 2;	    break;	  case XSyncCATestType:	    mask &= ~XSyncCATestType;	    /* sanity check in SyncInitTrigger */	    pAlarm->trigger.test_type = *values++;	    break;	  case XSyncCADelta:	    mask &= ~XSyncCADelta;	    XSyncIntsToValue(&pAlarm->delta, values[1], values[0]);	    values += 2;	    break;	  case XSyncCAEvents:	    mask &= ~XSyncCAEvents;	    if ((*values != xTrue) && (*values != xFalse))	    {		client->errorValue = *values;		return BadValue;	    }	    status = SyncEventSelectForAlarm(pAlarm, client,					     (Bool)(*values++));	    if (status != Success)		return status;	    break;	  default:	    client->errorValue = mask;	    return BadValue;	}    }    /* "If the test-type is PositiveComparison or PositiveTransition     *  and delta is less than zero, or if the test-type is     *  NegativeComparison or NegativeTransition and delta is     *  greater than zero, a Match error is generated."     */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -