Files
TransPyC/includes/vthreading.vp

103 lines
2.7 KiB
Plaintext

import t, c
from stdint import *
from w32.win32base import *
from w32.win32process import CreateThread, GetExitCodeThread, GetCurrentThreadId, TlsAlloc, TlsFree, TlsGetValue, TlsSetValue
from w32.win32sync import WaitForSingleObject
# All lock classes are imported, and users can also import them as needed.
from lock import Lock
from event import Event
from condition import Condition
from rwlock import RWLock
class Thread:
"""Thread class, wraps Windows CreateThread.
Thread callback signature: def thread_func(arg: t.CPtr) -> t.CPtr
Note: Windows API limits the return value to DWORD (32-bit), so 64-bit pointers will be truncated.
If you need to return a 64-bit result, pass it via the arg parameter struct.
Usage:
def worker(arg: t.CPtr) -> t.CPtr:
# thread logic
return NULL
t: Thread = Thread(worker, arg_ptr)
t.start()
t.join()
"""
handle: HANDLE
thread_id: ULONG
target: VOIDPTR
arg: VOIDPTR
started: BOOL
def __init__(self, target: VOIDPTR, arg: VOIDPTR = NULL):
self.handle = NULL
self.thread_id = 0
self.target = target
self.arg = arg
self.started = FALSE
def start(self):
if self.started:
return
self.handle = CreateThread(NULL, 0, self.target, self.arg, 0, c.Addr(self.thread_id))
self.started = TRUE
def join(self, timeout_ms: ULONG = INFINITE) -> BOOL:
if not self.started:
return FALSE
result: ULONG = WaitForSingleObject(self.handle, timeout_ms)
return result == WAIT_OBJECT_0
def is_alive(self) -> BOOL:
if not self.started:
return FALSE
result: ULONG = WaitForSingleObject(self.handle, 0)
return result == WAIT_TIMEOUT
def get_exit_code(self) -> ULONG:
code: ULONG = 0
GetExitCodeThread(self.handle, c.Addr(code))
return code
def close(self):
if self.handle != NULL:
CloseHandle(self.handle)
self.handle = NULL
class local:
"""TLS (Thread Local Storage) encapsulation.
Usage:
tls: local = local()
tls.set(value_ptr)
val: t.CPtr = tls.get()
"""
index: ULONG
def __init__(self):
self.index = TlsAlloc()
def get(self) -> VOIDPTR:
return TlsGetValue(self.index)
def set(self, value: VOIDPTR) -> BOOL:
return TlsSetValue(self.index, value)
def free(self) -> BOOL:
return TlsFree(self.index)
def get_current_thread_id() -> ULONG:
"""Get current thread ID"""
return GetCurrentThreadId()
def sleep_ms(ms: ULONG):
"""Make the current thread sleep for a specified number of milliseconds"""
Sleep(ms)