Commit 5483290b authored by Lisa Avila's avatar Lisa Avila
Browse files

Added functionality to spawn a process. This process continues to execute

after control has been returned. The process can be terminated. A
vtkMutexFunctionLock is used to communicate the running status of a spawned
process from the main process.
parent 30577375
......@@ -62,8 +62,13 @@ vtkMultiThreader::vtkMultiThreader()
for ( i = 0; i < VTK_MAX_THREADS; i++ )
{
this->ThreadInfoArray[i].ThreadID = i;
this->MultipleMethod[i] = NULL;
this->ThreadInfoArray[i].ThreadID = i;
this->ThreadInfoArray[i].ActiveFlag = NULL;
this->ThreadInfoArray[i].ActiveFlagLock = NULL;
this->MultipleMethod[i] = NULL;
this->SpawnedThreadActiveFlag[i] = 0;
this->SpawnedThreadActiveFlagLock[i] = NULL;
this->SpawnedThreadInfoArray[i].ThreadID = 0;
}
this->SingleMethod = NULL;
......@@ -475,6 +480,140 @@ void vtkMultiThreader::MultipleMethodExecute()
#endif
}
int vtkMultiThreader::SpawnThread( vtkThreadFunctionType f, void *UserData )
{
int id;
#ifdef _WIN32
DWORD threadId;
#endif
id = 0;
while ( id < VTK_MAX_THREADS )
{
if ( this->SpawnedThreadActiveFlagLock[id] == NULL ) break;
id++;
}
if ( id >= VTK_MAX_THREADS )
{
vtkErrorMacro( << "You have too many active threads!" );
return -1;
}
this->SpawnedThreadActiveFlagLock[id] = vtkMutexFunctionLock::New();
vtkMutexLockFuncMacro(this->SpawnedThreadActiveFlagLock[id],this->SpawnedThreadActiveFlag[id]=1);
this->SpawnedThreadInfoArray[id].UserData = UserData;
this->SpawnedThreadInfoArray[id].NumberOfThreads = 1;
this->SpawnedThreadInfoArray[id].ActiveFlag =
&this->SpawnedThreadActiveFlag[id];
this->SpawnedThreadInfoArray[id].ActiveFlagLock =
this->SpawnedThreadActiveFlagLock[id];
// We are using sproc (on SGIs), pthreads(on Suns or HPs),
// CreateThread (on win32), or generating an error
#ifdef _WIN32
// Using CreateThread on a PC
//
this->SpawnedThreadProcessID[id] =
CreateThread(NULL, 0, f,
((void *)(&this->SpawnedThreadInfoArray[id])), 0, &threadId);
if (this->SpawnedThreadProcessID[id] == NULL)
{
vtkErrorMacro("Error in thread creation !!!");
}
#endif
#ifdef VTK_USE_SPROC
// Using sproc() on an SGI
//
this->SpawnedThreadProcessID[id] =
sproc( f, PR_SADDR, ( (void *)(&this->SpawnedThreadInfoArray[id]) ) );
#endif
#ifdef VTK_USE_PTHREADS
// Using POSIX threads
//
pthread_attr_t attr;
#ifdef VTK_HP_PTHREADS
pthread_attr_create( &attr );
#else
pthread_attr_init(&attr);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
#endif
#ifdef VTK_HP_PTHREADS
pthread_create( &(this->SpawnedThreadProcessID[id]),
attr, f,
( (void *)(&this->SpawnedThreadInfoArray[id]) ) );
#else
pthread_create( &(this->SpawnedThreadProcessID[id]),
&attr, f,
( (void *)(&this->SpawnedThreadInfoArray[id]) ) );
#endif
#endif
#ifndef _WIN32
#ifndef VTK_USE_SPROC
#ifndef VTK_USE_PTHREADS
// There is no multi threading, so there is only one thread.
// This won't work - so give an error message.
vtkErrorMacro( << "Cannot spawn thread in a single threaded environment!" );
this->SpawnedThreadActiveFlagLock[id]->Delete();
id = -1;
#endif
#endif
#endif
return id;
}
void vtkMultiThreader::TerminateThread( int ThreadID )
{
if ( !this->SpawnedThreadActiveFlag[ThreadID] ) {
return;
}
vtkMutexLockFuncMacro(this->SpawnedThreadActiveFlagLock[ThreadID],this->SpawnedThreadActiveFlag[ThreadID]=0);
#ifdef _WIN32
WaitForSingleObject(this->SpawnedThreadProcessID[ThreadID], INFINITE);
CloseHandle(this->SpawnedThreadProcessID[ThreadID]);
#endif
#ifdef VTK_USE_SPROC
siginfo_t info_ptr;
waitid( P_PID, (id_t) this->SpawnedThreadProcessID[ThreadID],
&info_ptr, WEXITED );
#endif
#ifdef VTK_USE_PTHREADS
pthread_join( this->SpawnedThreadProcessID[ThreadID], NULL );
#endif
#ifndef _WIN32
#ifndef VTK_USE_SPROC
#ifndef VTK_USE_PTHREADS
// There is no multi threading, so there is only one thread.
// This won't work - so give an error message.
vtkErrorMacro(<< "Cannot terminate thread in single threaded environment!");
#endif
#endif
#endif
this->SpawnedThreadActiveFlagLock[ThreadID]->Delete();
}
// Description:
// Print method for the multithreader
void vtkMultiThreader::PrintSelf(ostream& os, vtkIndent indent)
......
......@@ -49,6 +49,7 @@ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#define __vtkMultiThreader_h
#include "vtkObject.h"
#include "vtkMutexFunctionLock.h"
#ifdef VTK_USE_SPROC
#include <sys/types.h>
......@@ -91,14 +92,20 @@ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
// Otherwise the type is void which is correct for WIN32
// and SPROC
//BTX
#ifdef VTK_USE_SPROC
typedef int vtkThreadProcessIDType;
#endif
#ifdef VTK_USE_PTHREADS
typedef void *(*vtkThreadFunctionType)(void *);
typedef pthread_t vtkThreadProcessIDType;
#define VTK_THREAD_RETURN_VALUE NULL
#define VTK_THREAD_RETURN_TYPE void *
#endif
#ifdef _WIN32
typedef LPTHREAD_START_ROUTINE vtkThreadFunctionType;
typedef HANDLE vtkThreadProcessIDType;
#define VTK_THREAD_RETURN_VALUE 0
#define VTK_THREAD_RETURN_TYPE DWORD __stdcall
#endif
......@@ -106,6 +113,7 @@ typedef LPTHREAD_START_ROUTINE vtkThreadFunctionType;
#ifndef _WIN32
#ifndef VTK_USE_PTHREADS
typedef void (*vtkThreadFunctionType)(void *);
typedef int vtkThreadProcessIDType;
#define VTK_THREAD_RETURN_VALUE
#define VTK_THREAD_RETURN_TYPE void
#endif
......@@ -125,6 +133,8 @@ struct ThreadInfoStruct
{
int ThreadID;
int NumberOfThreads;
int *ActiveFlag;
vtkMutexFunctionLock *ActiveFlagLock;
void *UserData;
};
......@@ -176,6 +186,16 @@ public:
void SetMultipleMethod( int index, vtkThreadFunctionType,
void *data );
// Description:
// Create a new thread for the given function. Return a thread id
// which is a number between 0 and VTK_MAX_THREADS - 1. This id should
// be used to kill the thread at a later time.
int SpawnThread( vtkThreadFunctionType, void *data );
// Description:
// Terminate the thread that was created with a SpawnThreadExecute()
void TerminateThread( int thread_id );
protected:
// The number of threads to use
int NumberOfThreads;
......@@ -188,11 +208,20 @@ protected:
// The methods
vtkThreadFunctionType SingleMethod;
vtkThreadFunctionType MultipleMethod[VTK_MAX_THREADS];
// Storage of MutexFunctions and ints used to control spawned
// threads and the spawned thread ids
int SpawnedThreadActiveFlag[VTK_MAX_THREADS];
vtkMutexFunctionLock *SpawnedThreadActiveFlagLock[VTK_MAX_THREADS];
vtkThreadProcessIDType SpawnedThreadProcessID[VTK_MAX_THREADS];
ThreadInfoStruct SpawnedThreadInfoArray[VTK_MAX_THREADS];
//ETX
// Internal storage of the data
void *SingleData;
void *MultipleData[VTK_MAX_THREADS];
};
#endif
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment