/******************************************************************************** * * * Thread functions. These try to duplicate the functionality of tForth. * * * ********************************************************************************/ int createthread (int tattr, int ssize, int addr, int arg, int flags, int IDaddr ) { /* 236 */ unsigned long result = _beginthreadex ( (LPSECURITY_ATTRIBUTES) tattr, // pointer to thread security attributes (DWORD) ssize, // initial thread stack size, in bytes (LPTHREAD_START_ROUTINE) addr, // pointer to thread function (LPVOID) arg, // argument for new thread (DWORD) flags, // creation flags (LPDWORD) IDaddr); // pointer to returned thread identifier iserror = (result ? 0 : GetLastError()); return (int)result;} int exitthread (int code) { /* 237 */ _endthreadex (code); return iserror=0; } int waitforAND (int addrh, int count) { /* 238 */ int result = WaitForMultipleObjects ( (DWORD) count, // number of handles in handle array (CONST HANDLE *) addrh, // address of object-handle array TRUE, // wait flag: wait for ALL threads to finish INFINITE); // time-out interval in milliseconds: for ever iserror = (result == WAIT_FAILED) ? GetLastError() : 0; return result; } // Returns the array index of the object signaling first, -1 if the timer expired. int waitforOR (int addrh, int count, int timeout) { /* 239 */ int result = WaitForMultipleObjects ( (DWORD) count, // number of handles in handle array (CONST HANDLE *) addrh, // address of object-handle array FALSE, // wait flag: wait for ANY threads to finish (timeout == -1 ? INFINITE : timeout)); iserror = (result == WAIT_FAILED) ? GetLastError() : 0; return (result == WAIT_TIMEOUT) ? -1 : result-WAIT_OBJECT_0; } // A semaphore is simply an iForth VARIABLE . int initCS (HANDLE *semaphore) { /* 176 */ *semaphore = CreateMutex(NULL,0,NULL); return iserror=0; } // Waits for ownership of the specified mutex. int enterCS (HANDLE *semaphore) { /* 177 */ WaitForSingleObject( *semaphore, INFINITE ); return iserror=0; } // Releases ownership of the specified mutex. int leaveCS (HANDLE *semaphore) { /* 178 */ ReleaseMutex( *semaphore ); return iserror=0; } // Links are blocking named pipes. int createlink (char *name, int sz) { /* 179 */ HANDLE ret = CreateNamedPipe( makestr (name,sz), PIPE_ACCESS_DUPLEX | FILE_FLAG_WRITE_THROUGH, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, // maximum number of instances 4096, // output buffer size, in bytes (disregarded) 4096, // input buffer size, in bytes (disregarded) INFINITE, // time-out time, in milliseconds NULL); // address of security attributes structure if (ret==INVALID_HANDLE_VALUE) {iserror=GetLastError(); return 0;} iserror=0; return (int)ret; } // Read can be done with readnamedpipe(char *buf, int sz, HANDLE h) /* 233 */ // Write can be done with writenamedpipe(char *buf, int sz, HANDLE h) /* 234 */ // Close is not needed. You can do it by calling closenamedpipe(h) /* 235 */ int killthread(int h) { /* 198 */ iserror=0; return TerminateThread((HANDLE)h,0) ? 0 : GetLastError(); } int closehandle (int h) { /* 197 */ int ret = CloseHandle((HANDLE)h) ? 0 : GetLastError(); iserror = (ret != 0); return (int)ret; } // This layout must match the one in iForth! typedef struct channel { unsigned int id; unsigned int name; SOCKET lsock; SOCKET rsock; SOCKET wsock } channel; int select4 (channel *addrs[], int count, int tim) { /* 196 */ struct timeval timeout; fd_set readfds; int i,res; iserror=0; FD_ZERO(&readfds); timeout.tv_sec=0; timeout.tv_usec=1000*tim; for (i=0; irsock,&readfds); res=select(0,&readfds,NULL,NULL,&timeout); if (res==SOCKET_ERROR) {iserror = WSAGetLastError(); return -1;} if (res==0) return -1; // timeout for (i=0; irsock,&readfds)) return i; iserror=WSATRY_AGAIN; return -1; } /* EOF */