示例#1
0
/*	===== tls_alloc ================================================================
	PUBLIC. Allocate a new TLS index.
	================================================================================	*/
status_t tls_alloc (int* pIndex)
	{
	int index ;
	status_t status;
	if (!pIndex) return B_BAD_VALUE ;

	//	Check parameter.
	assert (pIndex != NULL) ;
	if (pIndex == NULL) return B_BAD_VALUE ;

	//	Get a new index (using mutual exclusion).
	if ((status = tls_index_mutex_p ()) == B_NO_ERROR)
		{
		status = tls_create_index (&index) ;
		tls_index_mutex_v () ;
		}
	if (status != B_NO_ERROR) 
		{
		//	Set to an invalid index (ie: use without error checking will 
		//	resolve to errors).
		*pIndex = -1 ;
		return status ;
		}

	//	Finish.
	*pIndex = index ;
	return B_NO_ERROR ;
	}
示例#2
0
/*	===== tls_get ==================================================================
	PUBLIC. Get a TLS data at an index.
	================================================================================	*/
status_t tls_get (int index, tls_data_t* pData) 
	{
	int indexOk ;
	_tls_thread_entry_t* e = NULL ;
	thread_id id ;
	status_t status ;

	//	Check parameter.
	assert (pData != NULL) ;
	if (pData == NULL) return B_BAD_VALUE ;
	*pData = TLS_INVALID_DATA ;
	assert (index >= 0) ;
	if (index < 0) return B_BAD_VALUE ;

	//	Check index value (verify index has been allocated).
	if ((status = tls_index_mutex_p ()) == B_NO_ERROR)
		{
		indexOk = tls_check_index (index) ;
		tls_index_mutex_v () ;
		}
	else
		return status ;
	if (!indexOk) return B_BAD_INDEX ;

	//	Get the entry for the thread.
	id = find_thread (NULL) ;
	if ((status = tls_entries_mutex_p ()) == B_NO_ERROR)
		{
		if ((status = tls_get_entry (id, &e)) != B_NO_ERROR)
			status = tls_create_entry (id, &e) ;
		tls_entries_mutex_v () ;
		}
	
	//	Get it using the get_inproc function.
	if (status == B_NO_ERROR)
		return tls_get_inproc (index, pData, e) ;
	else
		return status ;
	}
示例#3
0
/*	===== tls_free =================================================================
	PUBLIC. Free TLS index.
	================================================================================	*/
status_t tls_free (int index)
	{
	status_t status ;

	//	Check parameter.
	assert (index >= 0) ;
	if (index < 0) return B_BAD_INDEX ;

	//	Request to free the index (using mutual exclusion).
	if ((status = tls_index_mutex_p ()) == B_NO_ERROR)
		{
		if (tls_check_index (index))
			{
			tls_delete_index (index) ;
			}
		else
			status = B_BAD_INDEX ;
		tls_index_mutex_v () ;
		}

	//	Finish.
	return status ;
	}
示例#4
0
/*	===== tls_init =================================================================
	PRIVATE. Initialise TLS management. Called at dynamic module loading.
	Note: as we use Benaphore like mutexs, the semaphores initial count are 0.
	================================================================================	*/
status_t tls_init (int clientVersion)
	{
	int i ;
	status_t status ;
	int semCreatedCount = 0 ;

	//	Currently, the test is based on the same primary version number.
	if ((clientVersion & 0xFF000000) < (TLS_VERSION &0xFF000000)) return B_ERROR ;

	//	Create entries mutex. If the mutex already exist, the init phase is already
	//	done (or is running). In this case, we wait for the mutex to be released
	//	by its current owner, and then return doing nothing. 
	if (gm_mutex_entries != 0)
		{
		if ((status=tls_entries_mutex_p ()) != B_NO_ERROR)	// Wait for the mutex.
			goto ERROR_LABEL ;
		tls_entries_mutex_v ();	// Release it.
		return B_NO_ERROR ;	// Consider init already done.
		}
	else
		{
		//	Note: When the semaphore is created, gm_mutex_entries_val is with
		//	a value 1 (not 0). So during init phase other threads will block on
		//	semaphore.
		status = gm_mutex_entries = create_sem (0, "tls-entries") ;
		if (gm_mutex_entries < B_NO_ERROR) goto ERROR_LABEL ;
		semCreatedCount = 1 ;
		}
		
	//	Create indexs mutex.
	status = gm_mutex_indexs = create_sem (0, "tls-indexs") ;
	if (gm_mutex_indexs < B_NO_ERROR) goto ERROR_LABEL ;
	semCreatedCount = 2 ;

	//	Create	entry/exit mutex.
	status = gm_mutex_entry_exit = create_sem (0, "tls-entry-exit") ;
	if (gm_mutex_indexs < B_NO_ERROR) goto ERROR_LABEL ;
	semCreatedCount = 3 ;

	//	Initialize array of last recently used entries.
	for (i=0 ; i<THREAD_ENTRIES_RECENT_COUNT ; i++)
		gm_recent[i] = NULL ;

	//	Create tls ended thread management.
	status = gm_signalExit = create_sem (0, "tls-monitor-exit") ;
	if (gm_signalExit < B_NO_ERROR) goto ERROR_LABEL ;
	semCreatedCount = 4 ;
	status = gm_monitor = spawn_thread (monitoring, "tls_monitor", B_LOW_PRIORITY, NULL) ;
	if (gm_monitor != B_NO_MORE_THREADS && gm_monitor != B_NO_MEMORY)
		resume_thread (gm_monitor) ;
	else
		goto ERROR_LABEL ;

	//	Finish.
	tls_entries_mutex_v () ;
	tls_index_mutex_v () ;
	tls_entry_exit_mutex_v () ;
	gm_initOk = true ;
	return B_NO_ERROR ;

	ERROR_LABEL:
	//	Error processing goes here. Release the resources that may have been allocated.
	gm_monitor = 0 ;
	if (semCreatedCount >= 4)
		{
		delete_sem (gm_signalExit) ; 
		gm_signalExit = 0 ;
		}
	if (semCreatedCount >= 3)
		{
		delete_sem (gm_mutex_entry_exit) ;
		gm_mutex_entry_exit = 0 ;
		gm_mutex_entry_exit_val = 1 ;
		}
	if (semCreatedCount >= 2)
		{
		delete_sem (gm_mutex_indexs) ;
		gm_mutex_indexs = 0 ;
		gm_mutex_indexs_val = 1 ;
		}
	if (semCreatedCount >= 1)
		{
		delete_sem (gm_mutex_entries) ; 
		gm_mutex_entries = 0 ;
		gm_mutex_entries_val = 1 ;
		}
	//	Return the status got when the error was detected.
	return status ;
	}