Beispiel #1
0
void ILGCDeinit()
{
	_FinalizerStopFlag = 1;

	GC_TRACE("ILGCDeinit: Performing final GC [thread:%d]\n", (int)ILThreadSelf());

	/* Do a final GC */
	ILGCCollect();
	/* Cleanup the finalizer thread */
	if (_FinalizerThread && _FinalizerThreadStarted)
	{
		GC_TRACE("ILGCDeinit: Peforming last finalizer run [thread:%d]\n", (int)ILThreadSelf());

		ILWaitEventSet(_FinalizerSignal);
		
		GC_TRACE("ILGCDeinit: Waiting for finalizer thread to end [thread:%d]\n", (int)ILThreadSelf());

		/* Wait for the finalizer thread */
		if (ILThreadJoin(_FinalizerThread, 15000))
		{
			GC_TRACE("ILGCDeinit: Finalizer thread finished [thread:%d]\n", (int)ILThreadSelf());			
		}
		else
		{
			GC_TRACE("ILGCDeinit: Finalizer thread not responding [thread:%d]\n", (int)ILThreadSelf());
		}

		/* Destroy the finalizer thread */
		ILThreadDestroy(_FinalizerThread);			
	}

	_ILMutexDestroy(&_FinalizerLock);
}
Beispiel #2
0
/*
 * Invoke a delegate from a closure.
 */
static void DelegateInvoke(ffi_cif *cif, void *result,
						   void **args, void *delegate)
{
	ILThread *thread = ILThreadSelf();
	ILClassPrivate *classPrivate = GetObjectClassPrivate(delegate);
	ILExecProcess *process = classPrivate->process;
	ILDelegateInvokeParams params;

	params.thread = 0;
	params.cif = cif;
	params.result = result;
	params.args = args;
	params.delegate = (System_Delegate *)delegate;
	if(!thread)
	{
		/* callback was invoked by a non pnet thread. */
		
		ILThreadRunSelf(_DelegateInvokeFromNewThread, (void *)&params);
	}
	else
	{
		params.thread = _ILExecThreadFromThread(thread);

		if(params.thread)
		{
			IL_BEGIN_EXECPROCESS_SWITCH(params.thread, process)
			_DelegateInvoke(&params);
			IL_END_EXECPROCESS_SWITCH(params.thread)
		}
		else
		{
			/* thread is not registerd for managed execution */
			if((params.thread = ILThreadRegisterForManagedExecution(process, thread)))
Beispiel #3
0
/*
 * Waits for a handle and if an interrupt or abort is encountered during the
 * wait sequence the function will return the proper wait error code but only
 * after it has managed to aquire the handle (by continuously retrying).
 * If the wait times out, the handle will not be aquired and the function will
 * return with either IL_WAIT_TIMEOUT, IL_WAIT_ABORTED or IL_WAIT_INTERRUPTED.
 */
int _ILWaitOneBackupInterruptsAndAborts(ILWaitHandle *handle, int timeout)
{	
	ILThread *thread = ILThreadSelf();
	int result, retval = 0, threadstate = 0;
	
	for (;;)
	{
		/* Wait to re-acquire the monitor (add ourselves to the "ready queue") */
		result = ILWaitOne(handle, timeout);
		
		if (result < IL_WAIT_TIMEOUT)
		{
			/* We were aborted or interrupted.  Save the thread state
				and keep trying to reaquire the monitor */
			
			_ILMutexLock(&thread->lock);
			
			threadstate |= thread->state;
			
			if (result == IL_WAIT_INTERRUPTED)
			{
				/* Interrupted is cleared by ILWaitOne so save it manually */					
				threadstate |= IL_TS_INTERRUPTED;
			}
			
			thread->state &= ~(IL_TS_ABORT_REQUESTED | IL_TS_INTERRUPTED);

			if (result < retval)
			{
				retval = result;
			}
			
			_ILMutexUnlock(&thread->lock);
			
			continue;
		}
		else
		{	
			if (threadstate != 0)
			{					
				_ILMutexLock(&thread->lock);

				/* Set the thread state to the thread state that was stored 
					and clear the interrupted flag */
				thread->state |= (threadstate & ~IL_TS_INTERRUPTED);

				_ILMutexUnlock(&thread->lock);
			}	
			else
			{
				retval = result;
			}
			
			return retval;
		}
	}
}
Beispiel #4
0
int ILWaitOne(ILWaitHandle *handle, ILUInt32 timeout)
{
	ILThread *thread = ILThreadSelf();
	_ILWakeup *wakeup = &(thread->wakeup);
	int result;

	/* Enter the "wait/sleep/join" state */
	result = _ILEnterWait(thread);
	if(result != 0)
	{
		return result;
	}

	/* Set the limit for the thread's wakeup object */
	if(!_ILWakeupSetLimit(wakeup, 1))
	{
		return _ILLeaveWait(thread, IL_WAIT_INTERRUPTED);
	}

	/* Register this thread with the handle */
	result = (*(handle->registerFunc))(handle, wakeup);

	if(result == IL_WAITREG_ACQUIRED)
	{
		/* We were able to acquire the wait handle immediately */
		_ILWakeupAdjustLimit(wakeup, 0);
		return _ILLeaveWaitHandle(thread, handle, 0);
	}
	else if(result == IL_WAITREG_FAILED)
	{
		/* Something serious happened which prevented registration */
		_ILWakeupAdjustLimit(wakeup, 0);
		return _ILLeaveWait(thread, IL_WAIT_FAILED);
	}

	/* Wait until we are signalled, timed out, or interrupted */
	result = _ILWakeupWait(wakeup, timeout, 0);

	/* Unregister the thread from the wait handle */
	(*(handle->unregisterFunc))(handle, wakeup, (result <= 0));

	/* Tell the caller what happened */
	if(result > 0)
	{
		/* We have to account for "_ILLeaveWait" detecting interrupt
		   or abort after we already acquired the wait handle */
		return _ILLeaveWaitHandle(thread, handle, 0);
	}
	else if(result == 0)
	{
		return _ILLeaveWait(thread, IL_WAIT_TIMEOUT);
	}
	else
	{
		return _ILLeaveWait(thread, IL_WAIT_INTERRUPTED);
	}
}
Beispiel #5
0
/*
 * Invoke the delegate from a new thread.
 */
static void *_DelegateInvokeFromNewThread(void *params)
{
	ILThread *thread = ILThreadSelf();
	ILClassPrivate *classPrivate = GetObjectClassPrivate(((ILDelegateInvokeParams *)params)->delegate);
	ILExecProcess *process = classPrivate->process;

	if((((ILDelegateInvokeParams *)params)->thread = ILThreadRegisterForManagedExecution(process, thread)))
	{
		_DelegateInvoke((ILDelegateInvokeParams *)params);
		ILThreadUnregisterForManagedExecution(thread);
	}
	return 0;
}
Beispiel #6
0
/*
 *	Main entry point for the finalizer thread.
 */
static void _FinalizerThreadFunc(void *data)
{
	GC_TRACE("GC:_FinalizerThread: Finalizer thread started [thread:%d]\n", (int)ILThreadSelf());

	for (;;)
	{
		ILWaitOne(_FinalizerSignal, -1);

		GC_TRACE("GC:_FinalizerThread: Signal [thread:%d]\n", (int)ILThreadSelf());

		/* This *must* to be set before checking for !_FinalizersDisabled to prevent
		    a race with ILGCDisableFinalizers */

		_FinalizersRunning = 1;

		ILThreadMemoryBarrier();

		if (GC_should_invoke_finalizers() && !_FinalizersDisabled)
		{
			GC_TRACE("GC:_FinalizerThread: Finalizers running [thread:%d]\n", (int)ILThreadSelf());
			
			GC_invoke_finalizers();
			
			GC_TRACE("GC:_FinalizerThread: Finalizers finished [thread:%d]\n", (int)ILThreadSelf());
		}

		_FinalizersRunning = 0;

		ILThreadMemoryBarrier();
		
		if (_FinalizerStopFlag)
		{
			/* Exit finalizer thread after having invoked finalizers one last time */

			GC_TRACE("GC:_FinalizerThread: Finalizer thread finished [thread:%d]\n", (int)ILThreadSelf());

			ILWaitEventReset(_FinalizerSignal);
			/* Wake all waiting threads */
			ILWaitEventPulse(_FinalizerResponse);
			
			return;
		}

		GC_TRACE("GC:_FinalizerThread: Response [thread:%d]\n", (int)ILThreadSelf());

		ILWaitEventReset(_FinalizerSignal);

		/* Wake all waiting threads */
		ILWaitEventPulse(_FinalizerResponse);
	}
}
Beispiel #7
0
int ILWaitAll(ILWaitHandle **handles, ILUInt32 numHandles, ILUInt32 timeout)
{
	ILThread *thread = ILThreadSelf();
	_ILWakeup *wakeup = &(thread->wakeup);
	int result;
	ILUInt32 index, index2;
	ILWaitHandle *handle;
	ILUInt32 limit;

	/* Enter the "wait/sleep/join" state */
	result = _ILEnterWait(thread);
	if(result != 0)
	{
		return result;
	}

	/* Set the limit for the thread's wakeup object.  This may
	   be reduced later if we were able to acquire some objects
	   during the registration step */
	limit = numHandles;
	if(!_ILWakeupSetLimit(wakeup, limit))
	{
		return _ILLeaveWait(thread, IL_WAIT_INTERRUPTED);
	}

	/* Register this thread with all of the wait handles */
	for(index = 0; index < numHandles; ++index)
	{
		handle = handles[index];
		result = (*(handle->registerFunc))(handle, wakeup);
		if(result == IL_WAITREG_ACQUIRED)
		{
			/* We were able to acquire this wait handle immediately */
			--limit;
		}
		else if(result == IL_WAITREG_FAILED)
		{
			/* Something serious happened which prevented registration */
			_ILWakeupAdjustLimit(wakeup, 0);

			/* Unregister the handles we have registered so far */
			for(index2 = 0; index2 < index; ++index2)
			{
				handle = handles[index2];
				(*(handle->unregisterFunc))(handle, wakeup, 1);
			}
			return _ILLeaveWait(thread, IL_WAIT_FAILED);
		}
	}

	/* Adjust the wait limit to reflect handles we already acquired */
	_ILWakeupAdjustLimit(wakeup, limit);
	
	if (limit == 0)
	{
		/* No need to wait since we managed to aquire every handle immediately. */		
		result = 1;
	}
	else
	{
		/* Wait until we are signalled, timed out, or interrupted */
		result = _ILWakeupWait(wakeup, timeout, 0);
	}

	/* Unregister the thread from the wait handles */
	for(index = 0; index < numHandles; ++index)
	{
		handle = handles[index];
		(*(handle->unregisterFunc))(handle, wakeup, (result <= 0));
	}

	/* Tell the caller what happened */
	if(result > 0)
	{
		/* We have to account for "_ILLeaveWait" detecting interrupt
		   or abort after we already acquired the wait handles */
		result = _ILLeaveWait(thread, 0);
		if(result == 0)
		{
			return 0;
		}
		else
		{
			for(index = 0; index < numHandles; ++index)
			{
				handle = handles[index];
				(*(handle->unregisterFunc))(handle, wakeup, 1);
			}
			return result;
		}
	}
	else if(result == 0)
	{
		return _ILLeaveWait(thread, IL_WAIT_TIMEOUT);
	}
	else
	{
		return _ILLeaveWait(thread, IL_WAIT_INTERRUPTED);
	}
}
Beispiel #8
0
int ILWaitAny(ILWaitHandle **handles, ILUInt32 numHandles, ILUInt32 timeout)
{
	ILThread *thread = ILThreadSelf();
	_ILWakeup *wakeup = &(thread->wakeup);
	int result;
	ILUInt32 index, index2;
	ILWaitHandle *handle;
	ILWaitHandle *resultHandle;

	/* Enter the "wait/sleep/join" state */
	result = _ILEnterWait(thread);
	if(result != 0)
	{
		return result;
	}

	/* Set the limit for the thread's wakeup object */
	if(!_ILWakeupSetLimit(wakeup, 1))
	{
		return _ILLeaveWait(thread, IL_WAIT_INTERRUPTED);
	}

	/* Register this thread with all of the wait handles */
	for(index = 0; index < numHandles; ++index)
	{
		handle = handles[index];
		result = (*(handle->registerFunc))(handle, wakeup);
		if(result == IL_WAITREG_ACQUIRED)
		{
			/* We were able to acquire this wait handle immediately */
			_ILWakeupAdjustLimit(wakeup, 0);

			/* Unregister the handles we have registered so far */
			for(index2 = 0; index2 < index; ++index2)
			{
				handle = handles[index2];
				(*(handle->unregisterFunc))(handle, wakeup, 1);
			}
			return _ILLeaveWaitHandle(thread, handles[index], index);
		}
		else if(result == IL_WAITREG_FAILED)
		{
			/* Something serious happened which prevented registration */
			_ILWakeupAdjustLimit(wakeup, 0);

			/* Unregister the handles we have registered so far */
			for(index2 = 0; index2 < index; ++index2)
			{
				handle = handles[index2];
				(*(handle->unregisterFunc))(handle, wakeup, 1);
			}
			return _ILLeaveWait(thread, IL_WAIT_FAILED);
		}
	}

	/* Wait until we are signalled, timed out, or interrupted */
	resultHandle = 0;
	result = _ILWakeupWait(wakeup, timeout, (void *)&resultHandle);

	/* Unregister the thread from the wait handles */
	index2 = 0;
	for(index = 0; index < numHandles; ++index)
	{
		handle = handles[index];
		if(handle == resultHandle && result > 0)
		{
			index2 = index;
			(*(handle->unregisterFunc))(handle, wakeup, 0);
		}
		else
		{
			(*(handle->unregisterFunc))(handle, wakeup, 1);
		}
	}

	/* Tell the caller what happened */
	if(result > 0)
	{
		/* We have to account for "_ILLeaveWait" detecting interrupt
		   or abort after we already acquired the wait handle */
		return _ILLeaveWaitHandle(thread, resultHandle, (int)index2);
	}
	else if(result == 0)
	{
		return _ILLeaveWait(thread, IL_WAIT_TIMEOUT);
	}
	else
	{
		return _ILLeaveWait(thread, IL_WAIT_INTERRUPTED);
	}
}
Beispiel #9
0
/*
 * Notify the finalization thread that there is work to do.
 */
static int PrivateGCNotifyFinalize(int timeout, int ignoreDisabled)
{
	int result;
	
	if (_FinalizersDisabled && !ignoreDisabled)
	{
		return 0;
	}

	/* Prevent recursive finalization */
	if (_FinalizersRunningSynchronously || ILThreadSelf() == _FinalizerThread)
	{	
		return 0;
	}

#ifdef GC_TRY_INVOKE_SYNCHRONOUSLY

	/* Try to invoke synchronously (for performance & single threaded systems) */
	if (_InvokeFinalizersSynchronously() == 0)
	{
		return 0;
	}
	
#endif

	/* There is no finalizer thread!
	   We've already attempted to invoke synchronously (above) so just exit. */
	if (_FinalizerThread == 0)
	{
		return 0;
	}
	
	/* Finalizers need to be run on a seperate thread.
	   Start the finalizer thread if it hasn't been started */
	if (!_FinalizerThreadStarted)
	{
		_ILMutexLock(&_FinalizerLock);
		
		if (!_FinalizerThreadStarted)
		{
			if (ILThreadStart(_FinalizerThread) == 0)
			{
				/* Couldn't create the finalizer thread */

				GC_TRACE("PrivateGCInvokeFinalizers: Couldn't " \
						 "start finalizer thread [thread: %d]\n",
						 (int)ILThreadSelf());
				
				_ILMutexUnlock(&_FinalizerLock);

				return 0;
			}

			_FinalizerThreadStarted = 1;
		}

		_ILMutexUnlock(&_FinalizerLock);
	}

	/* Signal the finalizer thread */

	GC_TRACE("PrivateGCInvokeFinalizers: Invoking finalizers " \
			"and waiting [thread: %d]\n", (int)ILThreadSelf());

	result = ILSignalAndWait(_FinalizerSignal, _FinalizerResponse, timeout);
	
	GC_TRACE("PrivateGCInvokeFinalizers: Finalizers finished[thread: %d]\n", (int)ILThreadSelf());

	return result;
}