|
|
@ -27,14 +27,6 @@ |
|
|
|
*/ |
|
|
|
static struct Global_Data { |
|
|
|
SyMemBackend sAllocator; /* Global low level memory allocator */ |
|
|
|
const SyMutexMethods *pMutexMethods; /* Mutex methods */ |
|
|
|
SyMutex *pMutex; /* Global mutex */ |
|
|
|
sxu32 nThreadingLevel; /* Threading level: 0 == Single threaded/1 == Multi-Threaded |
|
|
|
* The threading level can be set using the [ph7_lib_config()] |
|
|
|
* interface with a configuration verb set to |
|
|
|
* PH7_LIB_CONFIG_THREAD_LEVEL_SINGLE or |
|
|
|
* PH7_LIB_CONFIG_THREAD_LEVEL_MULTI |
|
|
|
*/ |
|
|
|
const ph7_vfs *pVfs; /* Underlying virtual file system */ |
|
|
|
sxi32 nEngine; /* Total number of active engines */ |
|
|
|
ph7 *pEngines; /* List of active engine */ |
|
|
@ -44,23 +36,9 @@ static struct Global_Data { |
|
|
|
0, |
|
|
|
0, |
|
|
|
0, |
|
|
|
0, |
|
|
|
0, |
|
|
|
0, |
|
|
|
0 |
|
|
|
}; |
|
|
|
#define PH7_LIB_MAGIC 0xEA1495BA |
|
|
|
/* |
|
|
|
* Supported threading level. |
|
|
|
* PH7_THREAD_LEVEL_SINGLE: |
|
|
|
* In this mode,mutexing is disabled and the library can only be used by a single thread. |
|
|
|
* PH7_THREAD_LEVEL_MULTI |
|
|
|
* In this mode, all mutexes including the recursive mutexes on [ph7] objects |
|
|
|
* are enabled so that the application is free to share the same engine |
|
|
|
* between different threads at the same time. |
|
|
|
*/ |
|
|
|
#define PH7_THREAD_LEVEL_SINGLE 1 |
|
|
|
#define PH7_THREAD_LEVEL_MULTI 2 |
|
|
|
/* |
|
|
|
* Configure a running PH7 engine instance. |
|
|
|
* return PH7_OK on success.Any other return |
|
|
@ -186,63 +164,6 @@ static sxi32 PH7CoreConfigure(sxi32 nOp, va_list ap) { |
|
|
|
sMPGlobal.sAllocator.pUserData = pUserData; |
|
|
|
break; |
|
|
|
} |
|
|
|
case PH7_LIB_CONFIG_USER_MUTEX: { |
|
|
|
/* Use an alternative low-level mutex subsystem */ |
|
|
|
const SyMutexMethods *pMethods = va_arg(ap, const SyMutexMethods *); |
|
|
|
if(pMethods == 0) { |
|
|
|
rc = PH7_CORRUPT; |
|
|
|
} |
|
|
|
/* Sanity check */ |
|
|
|
if(pMethods->xEnter == 0 || pMethods->xLeave == 0 || pMethods->xNew == 0) { |
|
|
|
/* At least three criticial callbacks xEnter(),xLeave() and xNew() must be supplied */ |
|
|
|
rc = PH7_CORRUPT; |
|
|
|
break; |
|
|
|
} |
|
|
|
if(sMPGlobal.pMutexMethods) { |
|
|
|
/* Overwrite the previous mutex subsystem */ |
|
|
|
SyMutexRelease(sMPGlobal.pMutexMethods, sMPGlobal.pMutex); |
|
|
|
if(sMPGlobal.pMutexMethods->xGlobalRelease) { |
|
|
|
sMPGlobal.pMutexMethods->xGlobalRelease(); |
|
|
|
} |
|
|
|
sMPGlobal.pMutex = 0; |
|
|
|
} |
|
|
|
/* Initialize and install the new mutex subsystem */ |
|
|
|
if(pMethods->xGlobalInit) { |
|
|
|
rc = pMethods->xGlobalInit(); |
|
|
|
if(rc != PH7_OK) { |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
/* Create the global mutex */ |
|
|
|
sMPGlobal.pMutex = pMethods->xNew(SXMUTEX_TYPE_FAST); |
|
|
|
if(sMPGlobal.pMutex == 0) { |
|
|
|
/* |
|
|
|
* If the supplied mutex subsystem is so sick that we are unable to |
|
|
|
* create a single mutex,there is no much we can do here. |
|
|
|
*/ |
|
|
|
if(pMethods->xGlobalRelease) { |
|
|
|
pMethods->xGlobalRelease(); |
|
|
|
} |
|
|
|
rc = PH7_CORRUPT; |
|
|
|
break; |
|
|
|
} |
|
|
|
sMPGlobal.pMutexMethods = pMethods; |
|
|
|
if(sMPGlobal.nThreadingLevel == 0) { |
|
|
|
/* Set a default threading level */ |
|
|
|
sMPGlobal.nThreadingLevel = PH7_THREAD_LEVEL_MULTI; |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
case PH7_LIB_CONFIG_THREAD_LEVEL_SINGLE: |
|
|
|
/* Single thread mode(Only one thread is allowed to play with the library) */ |
|
|
|
sMPGlobal.nThreadingLevel = PH7_THREAD_LEVEL_SINGLE; |
|
|
|
break; |
|
|
|
case PH7_LIB_CONFIG_THREAD_LEVEL_MULTI: |
|
|
|
/* Multi-threading mode (library is thread safe and PH7 engines and virtual machines |
|
|
|
* may be shared between multiple threads). |
|
|
|
*/ |
|
|
|
sMPGlobal.nThreadingLevel = PH7_THREAD_LEVEL_MULTI; |
|
|
|
break; |
|
|
|
default: |
|
|
|
/* Unknown configuration option */ |
|
|
|
rc = PH7_CORRUPT; |
|
|
@ -278,8 +199,6 @@ int ph7_lib_config(int nConfigOp, ...) { |
|
|
|
*/ |
|
|
|
static sxi32 PH7CoreInitialize(void) { |
|
|
|
const ph7_vfs *pVfs; /* Built-in vfs */ |
|
|
|
const SyMutexMethods *pMutexMethods = 0; |
|
|
|
SyMutex *pMaster = 0; |
|
|
|
int rc; |
|
|
|
/* |
|
|
|
* If the library is already initialized,then a call to this routine |
|
|
@ -292,30 +211,6 @@ static sxi32 PH7CoreInitialize(void) { |
|
|
|
pVfs = PH7_ExportBuiltinVfs(); |
|
|
|
/* Install it */ |
|
|
|
ph7_lib_config(PH7_LIB_CONFIG_VFS, pVfs); |
|
|
|
if(sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_SINGLE) { |
|
|
|
pMutexMethods = sMPGlobal.pMutexMethods; |
|
|
|
if(pMutexMethods == 0) { |
|
|
|
/* Use the built-in mutex subsystem */ |
|
|
|
pMutexMethods = SyMutexExportMethods(); |
|
|
|
if(pMutexMethods == 0) { |
|
|
|
return PH7_CORRUPT; /* Can't happen */ |
|
|
|
} |
|
|
|
/* Install the mutex subsystem */ |
|
|
|
rc = ph7_lib_config(PH7_LIB_CONFIG_USER_MUTEX, pMutexMethods); |
|
|
|
if(rc != PH7_OK) { |
|
|
|
return rc; |
|
|
|
} |
|
|
|
} |
|
|
|
/* Obtain a static mutex so we can initialize the library without calling malloc() */ |
|
|
|
pMaster = SyMutexNew(pMutexMethods, SXMUTEX_TYPE_STATIC_1); |
|
|
|
if(pMaster == 0) { |
|
|
|
return PH7_CORRUPT; /* Can't happen */ |
|
|
|
} |
|
|
|
} |
|
|
|
/* Lock the master mutex */ |
|
|
|
rc = PH7_OK; |
|
|
|
SyMutexEnter(pMutexMethods, pMaster); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ |
|
|
|
if(sMPGlobal.nMagic != PH7_LIB_MAGIC) { |
|
|
|
if(sMPGlobal.sAllocator.pMethods == 0) { |
|
|
|
/* Install a memory subsystem */ |
|
|
|
rc = ph7_lib_config(PH7_LIB_CONFIG_USER_MALLOC, 0); /* zero mean use the built-in memory backend */ |
|
|
@ -324,20 +219,10 @@ static sxi32 PH7CoreInitialize(void) { |
|
|
|
goto End; |
|
|
|
} |
|
|
|
} |
|
|
|
if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE) { |
|
|
|
/* Protect the memory allocation subsystem */ |
|
|
|
rc = SyMemBackendMakeThreadSafe(&sMPGlobal.sAllocator, sMPGlobal.pMutexMethods); |
|
|
|
if(rc != PH7_OK) { |
|
|
|
goto End; |
|
|
|
} |
|
|
|
} |
|
|
|
/* Our library is initialized,set the magic number */ |
|
|
|
sMPGlobal.nMagic = PH7_LIB_MAGIC; |
|
|
|
rc = PH7_OK; |
|
|
|
} /* sMPGlobal.nMagic != PH7_LIB_MAGIC */ |
|
|
|
End: |
|
|
|
/* Unlock the master mutex */ |
|
|
|
SyMutexLeave(pMutexMethods, pMaster); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ |
|
|
|
return rc; |
|
|
|
} |
|
|
|
/* |
|
|
@ -391,18 +276,6 @@ static void PH7CoreShutdown(void) { |
|
|
|
pEngine = pNext; |
|
|
|
sMPGlobal.nEngine--; |
|
|
|
} |
|
|
|
/* Release the mutex subsystem */ |
|
|
|
if(sMPGlobal.pMutexMethods) { |
|
|
|
if(sMPGlobal.pMutex) { |
|
|
|
SyMutexRelease(sMPGlobal.pMutexMethods, sMPGlobal.pMutex); |
|
|
|
sMPGlobal.pMutex = 0; |
|
|
|
} |
|
|
|
if(sMPGlobal.pMutexMethods->xGlobalRelease) { |
|
|
|
sMPGlobal.pMutexMethods->xGlobalRelease(); |
|
|
|
} |
|
|
|
sMPGlobal.pMutexMethods = 0; |
|
|
|
} |
|
|
|
sMPGlobal.nThreadingLevel = 0; |
|
|
|
if(sMPGlobal.sAllocator.pMethods) { |
|
|
|
/* Release the memory backend */ |
|
|
|
SyMemBackendRelease(&sMPGlobal.sAllocator); |
|
|
@ -429,13 +302,7 @@ int ph7_lib_is_threadsafe(void) { |
|
|
|
if(sMPGlobal.nMagic != PH7_LIB_MAGIC) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE) { |
|
|
|
/* Muli-threading support is enabled */ |
|
|
|
return 1; |
|
|
|
} else { |
|
|
|
/* Single-threading */ |
|
|
|
return 0; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
} |
|
|
|
/* |
|
|
|
* [CAPIREF: ph7_lib_version()] |
|
|
@ -468,17 +335,9 @@ int ph7_config(ph7 *pEngine, int nConfigOp, ...) { |
|
|
|
if(PH7_ENGINE_MISUSE(pEngine)) { |
|
|
|
return PH7_CORRUPT; |
|
|
|
} |
|
|
|
/* Acquire engine mutex */ |
|
|
|
SyMutexEnter(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && |
|
|
|
PH7_THRD_ENGINE_RELEASE(pEngine)) { |
|
|
|
return PH7_ABORT; /* Another thread have released this instance */ |
|
|
|
} |
|
|
|
va_start(ap, nConfigOp); |
|
|
|
rc = EngineConfig(&(*pEngine), nConfigOp, ap); |
|
|
|
va_end(ap); |
|
|
|
/* Leave engine mutex */ |
|
|
|
SyMutexLeave(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
return rc; |
|
|
|
} |
|
|
|
/* |
|
|
@ -510,28 +369,15 @@ int ph7_init(ph7 **ppEngine) { |
|
|
|
if(rc != PH7_OK) { |
|
|
|
goto Release; |
|
|
|
} |
|
|
|
SyMemBackendDisbaleMutexing(&pEngine->sAllocator); |
|
|
|
/* Default configuration */ |
|
|
|
SyBlobInit(&pEngine->xConf.sErrConsumer, &pEngine->sAllocator); |
|
|
|
/* Install a default compile-time error consumer routine */ |
|
|
|
ph7_config(pEngine, PH7_CONFIG_ERR_OUTPUT, PH7_VmBlobConsumer, &pEngine->xConf.sErrConsumer); |
|
|
|
/* Built-in vfs */ |
|
|
|
pEngine->pVfs = sMPGlobal.pVfs; |
|
|
|
if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE) { |
|
|
|
/* Associate a recursive mutex with this instance */ |
|
|
|
pEngine->pMutex = SyMutexNew(sMPGlobal.pMutexMethods, SXMUTEX_TYPE_RECURSIVE); |
|
|
|
if(pEngine->pMutex == 0) { |
|
|
|
rc = PH7_NOMEM; |
|
|
|
goto Release; |
|
|
|
} |
|
|
|
} |
|
|
|
/* Link to the list of active engines */ |
|
|
|
/* Enter the global mutex */ |
|
|
|
SyMutexEnter(sMPGlobal.pMutexMethods, sMPGlobal.pMutex); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ |
|
|
|
MACRO_LD_PUSH(sMPGlobal.pEngines, pEngine); |
|
|
|
sMPGlobal.nEngine++; |
|
|
|
/* Leave the global mutex */ |
|
|
|
SyMutexLeave(sMPGlobal.pMutexMethods, sMPGlobal.pMutex); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ |
|
|
|
/* Write a pointer to the new instance */ |
|
|
|
*ppEngine = pEngine; |
|
|
|
return PH7_OK; |
|
|
@ -549,25 +395,11 @@ int ph7_release(ph7 *pEngine) { |
|
|
|
if(PH7_ENGINE_MISUSE(pEngine)) { |
|
|
|
return PH7_CORRUPT; |
|
|
|
} |
|
|
|
/* Acquire engine mutex */ |
|
|
|
SyMutexEnter(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && |
|
|
|
PH7_THRD_ENGINE_RELEASE(pEngine)) { |
|
|
|
return PH7_ABORT; /* Another thread have released this instance */ |
|
|
|
} |
|
|
|
/* Release the engine */ |
|
|
|
rc = EngineRelease(&(*pEngine)); |
|
|
|
/* Leave engine mutex */ |
|
|
|
SyMutexLeave(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
/* Release engine mutex */ |
|
|
|
SyMutexRelease(sMPGlobal.pMutexMethods, pEngine->pMutex) /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
/* Enter the global mutex */ |
|
|
|
SyMutexEnter(sMPGlobal.pMutexMethods, sMPGlobal.pMutex); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ |
|
|
|
/* Unlink from the list of active engines */ |
|
|
|
MACRO_LD_REMOVE(sMPGlobal.pEngines, pEngine); |
|
|
|
sMPGlobal.nEngine--; |
|
|
|
/* Leave the global mutex */ |
|
|
|
SyMutexLeave(sMPGlobal.pMutexMethods, sMPGlobal.pMutex); /* NO-OP if sMPGlobal.nThreadingLevel == PH7_THREAD_LEVEL_SINGLE */ |
|
|
|
/* Release the memory chunk allocated to this engine */ |
|
|
|
SyMemBackendPoolFree(&sMPGlobal.sAllocator, pEngine); |
|
|
|
return rc; |
|
|
@ -664,13 +496,6 @@ static sxi32 ProcessSourceFile( |
|
|
|
if(rc != PH7_OK) { |
|
|
|
goto Release; |
|
|
|
} |
|
|
|
if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE) { |
|
|
|
/* Associate a recursive mutex with this instance */ |
|
|
|
pVm->pMutex = SyMutexNew(sMPGlobal.pMutexMethods, SXMUTEX_TYPE_RECURSIVE); |
|
|
|
if(pVm->pMutex == 0) { |
|
|
|
goto Release; |
|
|
|
} |
|
|
|
} |
|
|
|
/* Script successfully compiled,link to the list of active virtual machines */ |
|
|
|
MACRO_LD_PUSH(pEngine->pVms, pVm); |
|
|
|
pEngine->iVm++; |
|
|
@ -697,16 +522,8 @@ int ph7_compile_code(ph7 *pEngine, const char *zSource, int nLen, ph7_vm **ppOut |
|
|
|
nLen = (int)SyStrlen(zSource); |
|
|
|
} |
|
|
|
SyStringInitFromBuf(&sScript, zSource, nLen); |
|
|
|
/* Acquire engine mutex */ |
|
|
|
SyMutexEnter(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && |
|
|
|
PH7_THRD_ENGINE_RELEASE(pEngine)) { |
|
|
|
return PH7_ABORT; /* Another thread have released this instance */ |
|
|
|
} |
|
|
|
/* Compile the script */ |
|
|
|
rc = ProcessSourceFile(&(*pEngine), ppOutVm, &sScript, 0); |
|
|
|
/* Leave engine mutex */ |
|
|
|
SyMutexLeave(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
/* Compilation result */ |
|
|
|
return rc; |
|
|
|
} |
|
|
@ -721,12 +538,6 @@ int ph7_compile_file(ph7 *pEngine, const char *zFilePath, ph7_vm **ppOutVm) { |
|
|
|
if(PH7_ENGINE_MISUSE(pEngine) || SX_EMPTY_STR(zFilePath)) { |
|
|
|
return PH7_CORRUPT; |
|
|
|
} |
|
|
|
/* Acquire engine mutex */ |
|
|
|
SyMutexEnter(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && |
|
|
|
PH7_THRD_ENGINE_RELEASE(pEngine)) { |
|
|
|
return PH7_ABORT; /* Another thread have released this instance */ |
|
|
|
} |
|
|
|
/* |
|
|
|
* Check if the underlying vfs implement the memory map |
|
|
|
* [i.e: mmap() under UNIX/MapViewOfFile() under windows] function. |
|
|
@ -754,8 +565,6 @@ int ph7_compile_file(ph7 *pEngine, const char *zFilePath, ph7_vm **ppOutVm) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
/* Leave engine mutex */ |
|
|
|
SyMutexLeave(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
/* Compilation result */ |
|
|
|
return rc; |
|
|
|
} |
|
|
@ -787,18 +596,10 @@ int ph7_vm_config(ph7_vm *pVm, int iConfigOp, ...) { |
|
|
|
if(PH7_VM_MISUSE(pVm)) { |
|
|
|
return PH7_CORRUPT; |
|
|
|
} |
|
|
|
/* Acquire VM mutex */ |
|
|
|
SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && |
|
|
|
PH7_THRD_VM_RELEASE(pVm)) { |
|
|
|
return PH7_ABORT; /* Another thread have released this instance */ |
|
|
|
} |
|
|
|
/* Configure the virtual machine */ |
|
|
|
va_start(ap, iConfigOp); |
|
|
|
rc = PH7_VmConfigure(&(*pVm), iConfigOp, ap); |
|
|
|
va_end(ap); |
|
|
|
/* Leave VM mutex */ |
|
|
|
SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
return rc; |
|
|
|
} |
|
|
|
/* |
|
|
@ -811,20 +612,12 @@ int ph7_vm_exec(ph7_vm *pVm, int *pExitStatus) { |
|
|
|
if(PH7_VM_MISUSE(pVm)) { |
|
|
|
return PH7_CORRUPT; |
|
|
|
} |
|
|
|
/* Acquire VM mutex */ |
|
|
|
SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && |
|
|
|
PH7_THRD_VM_RELEASE(pVm)) { |
|
|
|
return PH7_ABORT; /* Another thread have released this instance */ |
|
|
|
} |
|
|
|
/* Execute PH7 byte-code */ |
|
|
|
rc = PH7_VmByteCodeExec(&(*pVm)); |
|
|
|
if(pExitStatus) { |
|
|
|
/* Exit status */ |
|
|
|
*pExitStatus = pVm->iExitStatus; |
|
|
|
} |
|
|
|
/* Leave VM mutex */ |
|
|
|
SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
/* Execution result */ |
|
|
|
return rc; |
|
|
|
} |
|
|
@ -838,15 +631,7 @@ int ph7_vm_reset(ph7_vm *pVm) { |
|
|
|
if(PH7_VM_MISUSE(pVm)) { |
|
|
|
return PH7_CORRUPT; |
|
|
|
} |
|
|
|
/* Acquire VM mutex */ |
|
|
|
SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && |
|
|
|
PH7_THRD_VM_RELEASE(pVm)) { |
|
|
|
return PH7_ABORT; /* Another thread have released this instance */ |
|
|
|
} |
|
|
|
rc = PH7_VmReset(&(*pVm)); |
|
|
|
/* Leave VM mutex */ |
|
|
|
SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
return rc; |
|
|
|
} |
|
|
|
/* |
|
|
@ -860,32 +645,14 @@ int ph7_vm_release(ph7_vm *pVm) { |
|
|
|
if(PH7_VM_MISUSE(pVm)) { |
|
|
|
return PH7_CORRUPT; |
|
|
|
} |
|
|
|
/* Acquire VM mutex */ |
|
|
|
SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && |
|
|
|
PH7_THRD_VM_RELEASE(pVm)) { |
|
|
|
return PH7_ABORT; /* Another thread have released this instance */ |
|
|
|
} |
|
|
|
pEngine = pVm->pEngine; |
|
|
|
rc = PH7_VmRelease(&(*pVm)); |
|
|
|
/* Leave VM mutex */ |
|
|
|
SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
/* free VM mutex */ |
|
|
|
SyMutexRelease(sMPGlobal.pMutexMethods, pVm->pMutex); |
|
|
|
if(rc == PH7_OK) { |
|
|
|
/* Unlink from the list of active VM */ |
|
|
|
/* Acquire engine mutex */ |
|
|
|
SyMutexEnter(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && |
|
|
|
PH7_THRD_ENGINE_RELEASE(pEngine)) { |
|
|
|
return PH7_ABORT; /* Another thread have released this instance */ |
|
|
|
} |
|
|
|
MACRO_LD_REMOVE(pEngine->pVms, pVm); |
|
|
|
pEngine->iVm--; |
|
|
|
/* Release the memory chunk allocated to this VM */ |
|
|
|
SyMemBackendPoolFree(&pEngine->sAllocator, pVm); |
|
|
|
/* Leave engine mutex */ |
|
|
|
SyMutexLeave(sMPGlobal.pMutexMethods, pEngine->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
} |
|
|
|
return rc; |
|
|
|
} |
|
|
@ -907,16 +674,8 @@ int ph7_create_function(ph7_vm *pVm, const char *zName, int (*xFunc)(ph7_context |
|
|
|
if(sName.nByte < 1 || xFunc == 0) { |
|
|
|
return PH7_CORRUPT; |
|
|
|
} |
|
|
|
/* Acquire VM mutex */ |
|
|
|
SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && |
|
|
|
PH7_THRD_VM_RELEASE(pVm)) { |
|
|
|
return PH7_ABORT; /* Another thread have released this instance */ |
|
|
|
} |
|
|
|
/* Install the foreign function */ |
|
|
|
rc = PH7_VmInstallForeignFunction(&(*pVm), &sName, xFunc, pUserData); |
|
|
|
/* Leave VM mutex */ |
|
|
|
SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
return rc; |
|
|
|
} |
|
|
|
/* |
|
|
@ -930,12 +689,6 @@ int ph7_delete_function(ph7_vm *pVm, const char *zName) { |
|
|
|
if(PH7_VM_MISUSE(pVm)) { |
|
|
|
return PH7_CORRUPT; |
|
|
|
} |
|
|
|
/* Acquire VM mutex */ |
|
|
|
SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && |
|
|
|
PH7_THRD_VM_RELEASE(pVm)) { |
|
|
|
return PH7_ABORT; /* Another thread have released this instance */ |
|
|
|
} |
|
|
|
/* Perform the deletion */ |
|
|
|
rc = SyHashDeleteEntry(&pVm->hHostFunction, (const void *)zName, SyStrlen(zName), (void **)&pFunc); |
|
|
|
if(rc == PH7_OK) { |
|
|
@ -944,8 +697,6 @@ int ph7_delete_function(ph7_vm *pVm, const char *zName) { |
|
|
|
SyMemBackendFree(&pVm->sAllocator, (void *)SyStringData(&pFunc->sName)); |
|
|
|
SyMemBackendPoolFree(&pVm->sAllocator, pFunc); |
|
|
|
} |
|
|
|
/* Leave VM mutex */ |
|
|
|
SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
return rc; |
|
|
|
} |
|
|
|
/* |
|
|
@ -970,16 +721,8 @@ int ph7_create_constant(ph7_vm *pVm, const char *zName, void (*xExpand)(ph7_valu |
|
|
|
if(xExpand == 0) { |
|
|
|
return PH7_CORRUPT; |
|
|
|
} |
|
|
|
/* Acquire VM mutex */ |
|
|
|
SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && |
|
|
|
PH7_THRD_VM_RELEASE(pVm)) { |
|
|
|
return PH7_ABORT; /* Another thread have released this instance */ |
|
|
|
} |
|
|
|
/* Perform the registration */ |
|
|
|
rc = PH7_VmRegisterConstant(&(*pVm), &sName, xExpand, pUserData, TRUE); |
|
|
|
/* Leave VM mutex */ |
|
|
|
SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
return rc; |
|
|
|
} |
|
|
|
/* |
|
|
@ -993,12 +736,6 @@ int ph7_delete_constant(ph7_vm *pVm, const char *zName) { |
|
|
|
if(PH7_VM_MISUSE(pVm)) { |
|
|
|
return PH7_CORRUPT; |
|
|
|
} |
|
|
|
/* Acquire VM mutex */ |
|
|
|
SyMutexEnter(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
if(sMPGlobal.nThreadingLevel > PH7_THREAD_LEVEL_SINGLE && |
|
|
|
PH7_THRD_VM_RELEASE(pVm)) { |
|
|
|
return PH7_ABORT; /* Another thread have released this instance */ |
|
|
|
} |
|
|
|
/* Query the constant hashtable */ |
|
|
|
rc = SyHashDeleteEntry(&pVm->hConstant, (const void *)zName, SyStrlen(zName), (void **)&pCons); |
|
|
|
if(rc == PH7_OK) { |
|
|
@ -1006,8 +743,6 @@ int ph7_delete_constant(ph7_vm *pVm, const char *zName) { |
|
|
|
SyMemBackendFree(&pVm->sAllocator, (void *)SyStringData(&pCons->sName)); |
|
|
|
SyMemBackendPoolFree(&pVm->sAllocator, pCons); |
|
|
|
} |
|
|
|
/* Leave VM mutex */ |
|
|
|
SyMutexLeave(sMPGlobal.pMutexMethods, pVm->pMutex); /* NO-OP if sMPGlobal.nThreadingLevel != PH7_THREAD_LEVEL_MULTI */ |
|
|
|
return rc; |
|
|
|
} |
|
|
|
/* |
|
|
|