* (c) sof, 2002-2003.
*/
#include "Rts.h"
+#include "RtsUtils.h"
#include <windows.h>
#include <stdio.h>
#include "Schedule.h"
static CRITICAL_SECTION queue_lock;
static HANDLE completed_req_event;
+static HANDLE abandon_req_wait;
+static HANDLE wait_handles[2];
static CompletedReq completedTable[MAX_REQUESTS];
static int completed_hw;
static int issued_reqs;
static void
onIOComplete(unsigned int reqID,
- void* param STG_UNUSED,
int fd STG_UNUSED,
int len,
- char* buf STG_UNUSED,
+ void* buf STG_UNUSED,
int errCode)
{
/* Deposit result of request in queue/table */
#if 0
fprintf(stderr, "addIOReq: %d %d %d\n", fd, forWriting, len); fflush(stderr);
#endif
- return AddIORequest(fd,forWriting,isSock,len,buf,0,onIOComplete);
+ return AddIORequest(fd,forWriting,isSock,len,buf,onIOComplete);
}
+unsigned int
+addDelayRequest(int msecs)
+{
+ EnterCriticalSection(&queue_lock);
+ issued_reqs++;
+ LeaveCriticalSection(&queue_lock);
+#if 0
+ fprintf(stderr, "addDelayReq: %d\n", msecs); fflush(stderr);
+#endif
+ return AddDelayRequest(msecs,onIOComplete);
+}
+
+unsigned int
+addDoProcRequest(void* proc, void* param)
+{
+ EnterCriticalSection(&queue_lock);
+ issued_reqs++;
+ LeaveCriticalSection(&queue_lock);
+#if 0
+ fprintf(stderr, "addProcReq: %p %p\n", proc, param); fflush(stderr);
+#endif
+ return AddProcRequest(proc,param,onIOComplete);
+}
+
+
int
startupAsyncIO()
{
return 0;
}
InitializeCriticalSection(&queue_lock);
- completed_req_event = CreateEvent (NULL, TRUE, FALSE, NULL);
+ /* Create a pair of events:
+ *
+ * - completed_req_event -- signals the deposit of request result; manual reset.
+ * - abandon_req_wait -- external OS thread tells current RTS/Scheduler
+ * thread to abandon wait for IO request completion.
+ * Auto reset.
+ */
+ completed_req_event = CreateEvent (NULL, TRUE, FALSE, NULL);
+ abandon_req_wait = CreateEvent (NULL, FALSE, FALSE, NULL);
+ wait_handles[0] = completed_req_event;
+ wait_handles[1] = abandon_req_wait;
completed_hw = 0;
- return 1;
+ return ( completed_req_event != INVALID_HANDLE_VALUE &&
+ abandon_req_wait != INVALID_HANDLE_VALUE );
}
void
/* empty table, drop lock and wait */
LeaveCriticalSection(&queue_lock);
if (wait) {
- WaitForSingleObject( completed_req_event, INFINITE );
+ DWORD dwRes = WaitForMultipleObjects(2, wait_handles, FALSE, INFINITE);
+ switch (dwRes) {
+ case WAIT_OBJECT_0:
+ break;
+ case WAIT_OBJECT_0 + 1:
+ case WAIT_TIMEOUT:
+ return 0;
+ default:
+ fprintf(stderr, "awaitRequests: unexpected wait return code %lu\n", dwRes); fflush(stderr);
+ return 0;
+ }
} else {
return 0; /* cannot happen */
}
switch(tso->why_blocked) {
case BlockedOnRead:
case BlockedOnWrite:
+ case BlockedOnDoProc:
if (tso->block_info.async_result->reqID == rID) {
/* Found the thread blocked waiting on request; stodgily fill
* in its result block.
}
break;
default:
+ if (tso->why_blocked != NotBlocked) {
+ barf("awaitRequests: odd thread state");
+ }
break;
}
prev = tso;
return 1;
}
}
+
+void
+abandonRequestWait()
+{
+ /* the event is auto-reset, but in case there's no thread
+ * already waiting on the event, we want to return it to
+ * a non-signalled state.
+ */
+ PulseEvent(abandon_req_wait);
+}