Exemple #1
0
void geventSendEvent(GSourceListener *psl) {
	gfxMutexEnter(&geventMutex);
	if (psl->pListener->callback) {

		// Mark it back as free and as sent. This is early to be marking as free but it protects
		//	if the callback alters the listener in any way
		psl->pListener->flags &= ~(GLISTENER_WITHSOURCE|GLISTENER_EVENTBUSY|GLISTENER_PENDING);
		gfxMutexExit(&geventMutex);

		// Do the callback
		psl->pListener->callback(psl->pListener->param, &psl->pListener->event);

	} else {
		// Wake up the listener
		psl->pListener->flags &= ~GLISTENER_WITHSOURCE;
		if ((psl->pListener->flags & GLISTENER_WAITING)) {
			psl->pListener->flags &= ~(GLISTENER_WAITING|GLISTENER_PENDING);
			gfxSemSignal(&psl->pListener->waitqueue);
		} else
			psl->pListener->flags |= GLISTENER_PENDING;

		// The listener thread will free the event buffer when ready
		gfxMutexExit(&geventMutex);
	}
}
Exemple #2
0
GEvent *geventEventWait(GListener *pl, delaytime_t timeout) {
	gfxMutexEnter(&geventMutex);
	// Don't allow waiting if we are on callbacks or if there is already a thread waiting
	if (pl->callback || (pl->flags & GLISTENER_WAITING)) {
		gfxMutexExit(&geventMutex);
		return 0;
	}

	// Check to see if there is a pending event ready for us
	if ((pl->flags & GLISTENER_PENDING)) {
		pl->flags &= ~GLISTENER_PENDING;				// We have now got this
		pl->flags |= GLISTENER_EVENTBUSY;				// Event buffer is definitely busy
		gfxMutexExit(&geventMutex);
		return &pl->event;
	}

	// No - wait for one.
	pl->flags &= ~GLISTENER_EVENTBUSY;				// Event buffer is definitely not busy
	pl->flags |= GLISTENER_WAITING;					// We will now be waiting on the thread
	gfxMutexExit(&geventMutex);
	if (gfxSemWait(&pl->waitqueue, timeout))
		return &pl->event;

	// Timeout - clear the waiting flag.
	// We know this is safe as any other thread will still think there is someone waiting.
	gfxMutexEnter(&geventMutex);
	pl->flags &= ~GLISTENER_WAITING;
	gfxMutexExit(&geventMutex);
	return 0;
}
Exemple #3
0
GEvent *geventGetEventBuffer(GSourceListener *psl) {
	gfxMutexEnter(&geventMutex);
	if ((psl->pListener->flags & GLISTENER_EVENTBUSY)) {
		// Oops - event buffer is still in use
		gfxMutexExit(&geventMutex);
		return 0;
	}

	// Allocate the event buffer
	psl->pListener->flags |= (GLISTENER_WITHSOURCE|GLISTENER_EVENTBUSY);
	gfxMutexExit(&geventMutex);
	return &psl->pListener->event;
}
Exemple #4
0
void geventSendEvent(GSourceListener *psl) {
	gfxMutexEnter(&geventMutex);
	if (psl->pListener->callback) {				// This test needs to be taken inside the mutex
		gfxMutexExit(&geventMutex);
		// We already know we have the event lock
		psl->pListener->callback(psl->pListener->param, &psl->pListener->event);

	} else {
		// Wake up the listener
		if (gfxSemCounter(&psl->pListener->waitqueue) <= 0)
			gfxSemSignal(&psl->pListener->waitqueue);
		gfxMutexExit(&geventMutex);
	}
}
Exemple #5
0
void geventDetachSource(GListener *pl, GSourceHandle gsh) {
	if (pl) {
		gfxMutexEnter(&geventMutex);
		deleteAssignments(pl, gsh);
		if (!gsh)
			doExitEvent(pl);
		gfxMutexExit(&geventMutex);
	}
}
Exemple #6
0
void gtimerJab(GTimer *pt) {
	gfxMutexEnter(&mutex);
	
	// Jab it!
	pt->flags |= GTIMER_FLG_JABBED;

	// Bump the thread
	gfxSemSignal(&waitsem);
	gfxMutexExit(&mutex);
}
Exemple #7
0
void geventRegisterCallback(GListener *pl, GEventCallbackFn fn, void *param) {
	if (pl) {
		gfxMutexEnter(&geventMutex);
		doExitEvent(pl);
		pl->param = param;						// Set the param
		pl->callback = fn;						// Set the callback function
		if (fn)
			pl->flags &= ~GLISTENER_EVENTBUSY;	// The event buffer is immediately available
		gfxMutexExit(&geventMutex);
	}
}
Exemple #8
0
void geventDetachSource(GListener *pl, GSourceHandle gsh) {
	if (pl) {
		gfxMutexEnter(&geventMutex);
		deleteAssignments(pl, gsh);
		if (!gsh && gfxSemCounter(&pl->waitqueue) < 0) {
			gfxSemWait(&pl->eventlock, TIME_INFINITE);		// Obtain the buffer lock
			pl->event.type = GEVENT_EXIT;					// Set up the EXIT event
			gfxSemSignal(&pl->waitqueue);					// Wake up the listener
			gfxSemSignal(&pl->eventlock);					// Release the buffer lock
		}
		gfxMutexExit(&geventMutex);
	}
}
Exemple #9
0
bool_t geventAttachSource(GListener *pl, GSourceHandle gsh, unsigned flags) {
	GSourceListener *psl, *pslfree;

	// Safety first
	if (!pl || !gsh) {
		GEVENT_ASSERT(FALSE);
		return FALSE;
	}

	gfxMutexEnter(&geventMutex);

	// Check if this pair is already in the table (scan for a free slot at the same time)
	pslfree = 0;
	for(psl = Assignments; psl < Assignments+GEVENT_MAX_SOURCE_LISTENERS; psl++) {
		
		if (pl == psl->pListener && gsh == psl->pSource) {
			// Just update the flags
			gfxSemWait(&pl->eventlock, TIME_INFINITE);		// Safety first - just in case a source is using it
			psl->listenflags = flags;
			gfxSemSignal(&pl->eventlock);			// Release this lock
			gfxMutexExit(&geventMutex);
			return TRUE;
		}
		if (!pslfree && !psl->pListener)
			pslfree = psl;
	}
	
	// A free slot was found - allocate it
	if (pslfree) {
		pslfree->pListener = pl;
		pslfree->pSource = gsh;
		pslfree->listenflags = flags;
		pslfree->srcflags = 0;
	}
	gfxMutexExit(&geventMutex);
	GEVENT_ASSERT(pslfree != 0);
	return pslfree != 0;
}
Exemple #10
0
void gtimerStart(GTimer *pt, GTimerFunction fn, void *param, bool_t periodic, delaytime_t millisec) {
	gfxMutexEnter(&mutex);
	
	// Start our thread if not already going
	if (!hThread) {
		hThread = gfxThreadCreate(waTimerThread, GTIMER_THREAD_WORKAREA_SIZE, GTIMER_THREAD_PRIORITY, GTimerThreadHandler, 0);
		if (hThread) {gfxThreadClose(hThread);}		// We never really need the handle again
	}

	// Is this already scheduled?
	if (pt->flags & GTIMER_FLG_SCHEDULED) {
		// Cancel it!
		if (pt->next == pt)
			pTimerHead = 0;
		else {
			pt->next->prev = pt->prev;
			pt->prev->next = pt->next;
			if (pTimerHead == pt)
				pTimerHead = pt->next;
		}
	}
	
	// Set up the timer structure
	pt->fn = fn;
	pt->param = param;
	pt->flags = GTIMER_FLG_SCHEDULED;
	if (periodic)
		pt->flags |= GTIMER_FLG_PERIODIC;
	if (millisec == TIME_INFINITE) {
		pt->flags |= GTIMER_FLG_INFINITE;
		pt->period = TIME_INFINITE;
	} else {
		pt->period = gfxMillisecondsToTicks(millisec);
		pt->when = gfxSystemTicks() + pt->period;
	}

	// Just pop it on the end of the queue
	if (pTimerHead) {
		pt->next = pTimerHead;
		pt->prev = pTimerHead->prev;
		pt->prev->next = pt;
		pt->next->prev = pt;
	} else
		pt->next = pt->prev = pTimerHead = pt;

	// Bump the thread
	if (!(pt->flags & GTIMER_FLG_INFINITE))
		gfxSemSignal(&waitsem);
	gfxMutexExit(&mutex);
}
Exemple #11
0
void geventRegisterCallback(GListener *pl, GEventCallbackFn fn, void *param) {
	if (pl) {
		gfxMutexEnter(&geventMutex);
		gfxSemWait(&pl->eventlock, TIME_INFINITE);			// Obtain the buffer lock
		pl->param = param;									// Set the param
		pl->callback = fn;									// Set the callback function
		if (gfxSemCounter(&pl->waitqueue) < 0) {
			pl->event.type = GEVENT_EXIT;			// Set up the EXIT event
			gfxSemSignal(&pl->waitqueue);			// Wake up the listener
		}
		gfxSemSignal(&pl->eventlock);				// Release the buffer lock
		gfxMutexExit(&geventMutex);
	}
}
Exemple #12
0
GSourceListener *geventGetSourceListener(GSourceHandle gsh, GSourceListener *lastlr) {
	GSourceListener *psl;

	// Safety first
	if (!gsh)
		return 0;

	gfxMutexEnter(&geventMutex);

	// Unlock the last listener event buffer if it wasn't used.
	if (lastlr && lastlr->pListener && (lastlr->pListener->flags & GLISTENER_WITHSOURCE))
		lastlr->pListener->flags &= ~(GLISTENER_WITHSOURCE|GLISTENER_EVENTBUSY);
		
	// Loop through the table looking for attachments to this source
	for(psl = lastlr ? (lastlr+1) : Assignments; psl < Assignments+GEVENT_MAX_SOURCE_LISTENERS; psl++) {
		if (gsh == psl->pSource) {
			gfxMutexExit(&geventMutex);
			return psl;
		}
	}
	gfxMutexExit(&geventMutex);
	return 0;
}
Exemple #13
0
GSourceListener *geventGetSourceListener(GSourceHandle gsh, GSourceListener *lastlr) {
	GSourceListener *psl;

	// Safety first
	if (!gsh)
		return 0;

	gfxMutexEnter(&geventMutex);

	// Unlock the last listener event buffer
	if (lastlr)
		gfxSemSignal(&lastlr->pListener->eventlock);
		
	// Loop through the table looking for attachments to this source
	for(psl = lastlr ? (lastlr+1) : Assignments; psl < Assignments+GEVENT_MAX_SOURCE_LISTENERS; psl++) {
		if (gsh == psl->pSource) {
			gfxSemWait(&psl->pListener->eventlock, TIME_INFINITE);		// Obtain a lock on the listener event buffer
			gfxMutexExit(&geventMutex);
			return psl;
		}
	}
	gfxMutexExit(&geventMutex);
	return 0;
}
Exemple #14
0
void gtimerStop(GTimer *pt) {
	gfxMutexEnter(&mutex);
	if (pt->flags & GTIMER_FLG_SCHEDULED) {
		// Cancel it!
		if (pt->next == pt)
			pTimerHead = 0;
		else {
			pt->next->prev = pt->prev;
			pt->prev->next = pt->next;
			if (pTimerHead == pt)
				pTimerHead = pt->next;
		}
		// Make sure we know the structure is dead!
		pt->flags = 0;
	}
	gfxMutexExit(&mutex);
}
Exemple #15
0
static DECLARE_THREAD_FUNCTION(GTimerThreadHandler, arg) {
	GTimer			*pt;
	systemticks_t	tm;
	systemticks_t	nxtTimeout;
	systemticks_t	lastTime;
	GTimerFunction	fn;
	void			*param;
	(void)			arg;

	nxtTimeout = TIME_INFINITE;
	lastTime = 0;
	while(1) {
		/* Wait for work to do. */
		gfxYield();					// Give someone else a go no matter how busy we are
		gfxSemWait(&waitsem, nxtTimeout);
		
	restartTimerChecks:
	
		// Our reference time
		tm = gfxSystemTicks();
		nxtTimeout = TIME_INFINITE;
		
		/* We need to obtain the mutex */
		gfxMutexEnter(&mutex);

		if (pTimerHead) {
			pt = pTimerHead;
			do {
				// Do we have something to do for this timer?
				if ((pt->flags & GTIMER_FLG_JABBED) || (!(pt->flags & GTIMER_FLG_INFINITE) && TimeIsWithin(pt->when, lastTime, tm))) {
				
					// Is this timer periodic?
					if ((pt->flags & GTIMER_FLG_PERIODIC) && pt->period != TIME_IMMEDIATE) {
						// Yes - Update ready for the next period
						if (!(pt->flags & GTIMER_FLG_INFINITE)) {
							// We may have skipped a period.
							// We use this complicated formulae rather than a loop
							//	because the gcc compiler stuffs up the loop so that it
							//	either loops forever or doesn't get executed at all.
							pt->when += ((tm + pt->period - pt->when) / pt->period) * pt->period;
						}

						// We are definitely no longer jabbed
						pt->flags &= ~GTIMER_FLG_JABBED;
						
					} else {
						// No - get us off the timers list
						if (pt->next == pt)
							pTimerHead = 0;
						else {
							pt->next->prev = pt->prev;
							pt->prev->next = pt->next;
							if (pTimerHead == pt)
								pTimerHead = pt->next;
						}
						pt->flags = 0;
					}
					
					// Call the callback function
					fn = pt->fn;
					param = pt->param;
					gfxMutexExit(&mutex);
					fn(param);
					
					// We no longer hold the mutex, the callback function may have taken a while
					// and our list may have been altered so start again!
					goto restartTimerChecks;
				}
				
				// Find when we next need to wake up
				if (!(pt->flags & GTIMER_FLG_INFINITE) && pt->when - tm < nxtTimeout)
					nxtTimeout = (pt->when - tm)/ticks2ms;
				pt = pt->next;
			} while(pt != pTimerHead);
		}

		// Ready for the next loop
		lastTime = tm;
		gfxMutexExit(&mutex);
	}
	THREAD_RETURN(0);
}
Exemple #16
0
void gfxSystemUnlock(void) {
	gfxMutexExit(&SystemMutex);
}
Exemple #17
0
		static void exitLock(GHandle gh) {
			gdispGUnsetClip(gh->display);
			gfxMutexExit(&gmutex);
		}
Exemple #18
0
void geventDetachSourceListeners(GSourceHandle gsh) {
	gfxMutexEnter(&geventMutex);
	deleteAssignments(0, gsh);
	gfxMutexExit(&geventMutex);
}