Changeset 12519


Ignore:
Timestamp:
Aug 3, 2009, 1:51:00 AM (10 years ago)
Author:
gb
Message:

Try to make Windows I/O (well, input at least) more interrupt-friendly.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/lisp-kernel/windows-calls.c

    r12270 r12519  
    294294
    295295ssize_t
    296 lisp_read(HANDLE hfile, void *buf, unsigned int count)
     296lisp_standard_read(HANDLE hfile, void *buf, unsigned int count)
    297297{
    298298  HANDLE hevent;
     
    338338  /* We block here */   
    339339  wait_result = WaitForSingleObjectEx(hevent, INFINITE, true);
     340
     341
     342
    340343  tcr->pending_io_info = NULL;
    341344  if (wait_result == WAIT_OBJECT_0) {
     
    367370  }
    368371}
     372
     373ssize_t
     374pipe_read(HANDLE hfile, void *buf, unsigned int count)
     375{
     376  DWORD navail;
     377
     378  do {
     379    navail = 0;
     380    PeekNamedPipe(hfile, NULL, 0, NULL, &navail, NULL);
     381    if (navail != 0) {
     382      return lisp_standard_read(hfile, buf, count);
     383    }
     384    if (SleepEx(50, TRUE) == WAIT_IO_COMPLETION) {
     385      errno = EINTR;
     386      return -1;
     387    }
     388  } while (1);
     389}
     390
     391ssize_t
     392console_read(HANDLE hfile, void *buf, unsigned int count)
     393{
     394  DWORD err, eventcount, i, n;
     395  INPUT_RECORD ir;
     396
     397  do {
     398    err = WaitForSingleObjectEx(hfile, INFINITE, TRUE);
     399    switch (err) {
     400    case WAIT_OBJECT_0:
     401      eventcount = 0;
     402      GetNumberOfConsoleInputEvents(hfile, &eventcount);
     403      for (i = 0; i < eventcount; i++) {
     404        PeekConsoleInput(hfile, &ir, 1, &n);
     405        if (ir.EventType == KEY_EVENT) {
     406          return lisp_standard_read(hfile, buf, count);
     407        } else {
     408          ReadConsoleInput(hfile, &ir, 1, &n);
     409        }
     410      }
     411      break;
     412    case WAIT_IO_COMPLETION:
     413      errno = EINTR;
     414      return -1;
     415      break;
     416    case WAIT_FAILED:
     417      _dosmaperr(GetLastError());
     418      return -1;
     419      break;
     420    }
     421  } while (1);
     422}
     423
     424ssize_t
     425lisp_read(HANDLE hfile, void *buf, unsigned int count) {
     426  switch(GetFileType(hfile)) {
     427  case FILE_TYPE_CHAR:
     428    return console_read(hfile, buf, count);
     429    break;
     430
     431  case FILE_TYPE_PIPE:          /* pipe or one of these newfangled socket things */
     432    {
     433      int socktype, optlen = sizeof(int);
     434      if ((getsockopt((SOCKET)hfile, SOL_SOCKET, SO_TYPE, (char *)&socktype, &optlen) != 0) && (GetLastError() == WSAENOTSOCK)) {
     435        return pipe_read(hfile, buf, count);
     436      }
     437    }
     438    /* It's a socket, fall through */
     439   
     440  case FILE_TYPE_DISK:
     441    return lisp_standard_read(hfile, buf, count);
     442    break;
     443
     444  default:
     445    errno = EBADF;
     446    return -1;
     447  }
     448}
     449
     450
    369451
    370452ssize_t
Note: See TracChangeset for help on using the changeset viewer.