summaryrefslogtreecommitdiff
path: root/src/htsthread.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/htsthread.c')
-rw-r--r--src/htsthread.c160
1 files changed, 141 insertions, 19 deletions
diff --git a/src/htsthread.c b/src/htsthread.c
index d403730..a766a40 100644
--- a/src/htsthread.c
+++ b/src/htsthread.c
@@ -34,15 +34,115 @@ Please visit our Website: http://www.httrack.com
/* Author: Xavier Roche */
/* ------------------------------------------------------------ */
+/* Internal engine bytecode */
+#define HTS_INTERNAL_BYTECODE
#include "htsglobal.h"
+#include "htsbase.h"
#include "htsthread.h"
+#if USE_BEGINTHREAD
+#if HTS_WIN
+#include <process.h>
+#endif
+#endif
+
+static int process_chain = 0;
+static PTHREAD_LOCK_TYPE process_chain_mutex;
+
+HTSEXT_API void htsthread_wait(void ) {
+ htsthread_wait_n(0);
+}
+
+HTSEXT_API void htsthread_wait_n(int n_wait) {
+#if USE_BEGINTHREAD
+ int wait = 0;
+ do {
+ htsSetLock(&process_chain_mutex, 1);
+ wait = (process_chain > n_wait );
+ htsSetLock(&process_chain_mutex, 0);
+ if (wait)
+ Sleep(100);
+ } while(wait);
+#endif
+}
+
+HTSEXT_API void htsthread_init(void ) {
+#if USE_BEGINTHREAD
+ assertf(process_chain == 0);
+ htsSetLock(&process_chain_mutex, -999);
+#endif
+}
+
+HTSEXT_API void htsthread_uninit(void ) {
+ htsthread_wait();
+#if USE_BEGINTHREAD
+ htsSetLock(&process_chain_mutex, -998);
+#endif
+}
+
+typedef struct {
+ PTHREAD_TYPE ( PTHREAD_TYPE_FNC *start_address )( void * );
+ void** arglist;
+} execth_args;
+static PTHREAD_TYPE PTHREAD_TYPE_FNC execth( void * arg )
+{
+ execth_args* args = (execth_args*) arg;
+ assertf(args != NULL);
+
+ htsSetLock(&process_chain_mutex, 1);
+ process_chain++;
+ assertf(process_chain > 0);
+ htsSetLock(&process_chain_mutex, 0);
+
+ (void) args->start_address(args->arglist);
+
+ htsSetLock(&process_chain_mutex, 1);
+ process_chain--;
+ assertf(process_chain >= 0);
+ htsSetLock(&process_chain_mutex, 0);
+
+ free(arg);
+ return PTHREAD_RETURN;
+}
+
+
+HTSEXT_API int hts_newthread( PTHREAD_TYPE ( PTHREAD_TYPE_FNC *start_address )( void * ), unsigned stack_size, void *arglist )
+{
+ execth_args* args = (execth_args*) malloc(sizeof(execth_args));
+ assertf(args != NULL);
+ args->start_address = start_address;
+ args->arglist = arglist;
+
+ /* create a thread */
+#ifdef _WIN32
+ if (_beginthread(execth, stack_size, args) == -1) {
+ free(args);
+ return -1;
+ }
+#else
+ {
+ PTHREAD_HANDLE handle = 0;
+ int retcode;
+ retcode = pthread_create(&handle, NULL, execth, args);
+ if (retcode != 0) { /* error */
+ free(args);
+ return -1;
+ } else {
+ /* detach the thread from the main process so that is can be independent */
+ pthread_detach(handle);
+ }
+ }
+#endif
+ return 0;
+}
+
+
// Threads - emulate _beginthread under Linux/Unix using pthread_XX
// Some changes will have to be done, see PTHREAD_RETURN,PTHREAD_TYPE
#if USE_PTHREAD
#include <pthread.h> /* _beginthread, _endthread */
-
+#if 0
unsigned long _beginthread( void* ( *start_address )( void * ), unsigned stack_size, void *arglist )
{
pthread_t th;
@@ -56,6 +156,7 @@ unsigned long _beginthread( void* ( *start_address )( void * ), unsigned stack_s
return 0;
}
#endif
+#endif
#if USE_BEGINTHREAD
/*
@@ -67,28 +168,49 @@ unsigned long _beginthread( void* ( *start_address )( void * ), unsigned stack_s
0 unlock the mutex
[-1 check if locked (always return 0 with mutex)]
-999 initialize
-*/
+ -998 free
+ */
HTSEXT_API int htsSetLock(PTHREAD_LOCK_TYPE* hMutex,int lock) {
#if HTS_WIN
/* lock */
- if (lock==1)
- WaitForSingleObject(*hMutex,INFINITE);
- /* unlock */
- else if (lock==0)
- ReleaseMutex(*hMutex);
- /* create */
- else if (lock==-999)
- *hMutex=CreateMutex(NULL,FALSE,NULL);
+ switch(lock) {
+ case 1: /* lock */
+ assertf(*hMutex != NULL);
+ WaitForSingleObject(*hMutex,INFINITE);
+ break;
+ case 0: /* unlock */
+ assertf(*hMutex != NULL);
+ ReleaseMutex(*hMutex);
+ break;
+ case -999: /* create */
+ *hMutex=CreateMutex(NULL,FALSE,NULL);
+ break;
+ case -998: /* destroy */
+ CloseHandle(*hMutex);
+ *hMutex = NULL;
+ break;
+ default:
+ assert(FALSE);
+ break;
+ }
#else
- /* lock */
- if (lock==1)
- pthread_mutex_lock(hMutex);
- /* unlock */
- else if (lock==0)
- pthread_mutex_unlock(hMutex);
- /* create */
- else if (lock==-999)
- pthread_mutex_init(hMutex,0);
+ switch(lock) {
+ case 1: /* lock */
+ pthread_mutex_lock(hMutex);
+ break;
+ case 0: /* unlock */
+ pthread_mutex_unlock(hMutex);
+ break;
+ case -999: /* create */
+ pthread_mutex_init(hMutex,0);
+ break;
+ case -998: /* destroy */
+ pthread_mutex_destroy(hMutex);
+ break;
+ default:
+ assert(0);
+ break;
+ }
#endif
return 0;
}