1
0
forked from 0ad/0ad

add sem_msgwait_np for philip/use with atlas. add API fail reporting for sem_*

networkInternal - remove E* error codes; rely on system <errno.h> header
wposix: add all SUSv3 error codes; value = that of CRT (where
available), otherwise the linux value

This was SVN commit r3087.
This commit is contained in:
janwas 2005-11-03 07:26:38 +00:00
parent 7bfe647366
commit 668794e61d
4 changed files with 157 additions and 83 deletions

View File

@ -67,65 +67,6 @@ extern "C" {
#endif
//
// <errno.h>
//
#include <errno.h>
// not defined there:
#define EINPROGRESS 100000
#define ETIMEDOUT (60) // matches NetworkInternal.h def
/*
enum
{
EINPROGRESS = 1000, // Operation in progress.
ENOMEM // Not enough space.
EACCES, // Permission denied.
EADDRINUSE, // Address in use.
EADDRNOTAVAIL, // Address not available.
EAGAIN, // Resource unavailable, try again (may be the same value as EWOULDBLOCK]).
EALREADY, // Connection already in progress.
EBADF, // Bad file descriptor.
ECANCELED, // Operation canceled.
ECONNABORTED, // Connection aborted.
ECONNREFUSED, // Connection refused.
ECONNRESET, // Connection reset.
EDOM, // Mathematics argument out of domain of function.
EEXIST, // File exists.
EFAULT, // Bad address.
EHOSTUNREACH, // Host is unreachable.
EINTR, // Interrupted function.
EINVAL, // Invalid argument.
EISCONN, // Socket is connected.
EISDIR, // Is a directory.
ENAMETOOLONG, // Filename too long.
ENETDOWN, // Network is down.
ENETRESET, // Connection aborted by network.
ENETUNREACH, // Network unreachable.
ENOENT, // No such file or directory.
ENOEXEC, // Executable file format error.
ENOSPC, // No space left on device.
ENOSYS, // Function not supported.
ENOTCONN, // The socket is not connected.
ENOTDIR, // Not a directory.
ENOTEMPTY, // Directory not empty.
ENOTSOCK, // Not a socket.
ENOTSUP, // Not supported.
EOVERFLOW, // Value too large to be stored in data type.
EPERM, // Operation not permitted.
EPIPE, // Broken pipe.
EPROTO, // Protocol error.
ERANGE, // Result too large.
ETIMEDOUT, // Connection timed out.
EWOULDBLOCK // Operation would block (may be the same value as EAGAIN]).
};
*/
//
// sys/stat.h
//
@ -375,6 +316,97 @@ struct utsname
extern int uname(struct utsname*);
//
// <errno.h>
//
#include <errno.h>
// this is an exhaustive list of SUSv3 error codes;
// see http://www.opengroup.org/onlinepubs/009695399/basedefs/errno.h.html .
// .. the following are already correctly defined by VC errno.h:
#if 0
#define EPERM 1 // Operation not permitted
#define ENOENT 2 // No such file or directory
#define ESRCH 3 // No such process
#define EINTR 4 // Interrupted system call
#define EIO 5 // I/O error
#define ENXIO 6 // No such device or address
#define E2BIG 7 // Argument list too long
#define ENOEXEC 8 // Exec format error
#define EBADF 9 // Bad file number
#define ECHILD 10 // No child processes
#define EAGAIN 11 // Try again
#define ENOMEM 12 // Out of memory
#define EACCES 13 // Permission denied
#define EFAULT 14 // Bad address
#define EBUSY 16 // Device or resource busy
#define EEXIST 17 // File exists
#define ENODEV 19 // No such device
#define ENOTDIR 20 // Not a directory
#define EISDIR 21 // Is a directory
#define EINVAL 22 // Invalid argument
#define ENFILE 23 // File table overflow
#define EMFILE 24 // Too many open files
#define ENOTTY 25 // Not a typewriter
#define EFBIG 27 // File too large
#define ENOSPC 28 // No space left on device
#define ESPIPE 29 // Illegal seek
#define EMLINK 31 // Too many links
#define EPIPE 32 // Broken pipe
#define EDOM 33 // Math argument out of domain of func
#define ERANGE 34 // Math result not representable
#endif
// .. the following are unfortunately defined differently by VC errno.h;
// we have to stick with those interpretations because they are set
// by already-compiled CRT code.
#if 0
#define EDEADLK 35 // Resource deadlock would occur
#define ENAMETOOLONG 36 // File name too long
#define ENOLCK 37 // No record locks available
#define ENOSYS 38 // Function not implemented
#define ENOTEMPTY 39 // Directory not empty
#define EILSEQ 84 // Illegal byte sequence
#endif
// .. the following aren't yet defined; we take on the Linux values for
// simplicity (why assign different values?)
#define ELOOP 40 // Too many symbolic links encountered
#define ENOMSG 42 // No message of desired type
#define EIDRM 43 // Identifier removed
#define EWOULDBLOCK EAGAIN // Operation would block
#define ENOLINK 67 // Reserved
#define EPROTO 71 // Protocol error
#define EMULTIHOP 72 // Reserved
#define EBADMSG 74 // Not a data message
#define EOVERFLOW 75 // Value too large for defined data type
#define ENOTSOCK 88 // Socket operation on non-socket
#define EDESTADDRREQ 89 // Destination address required
#define EMSGSIZE 90 // Message too long
#define EPROTOTYPE 91 // Protocol wrong type for socket
#define ENOPROTOOPT 92 // Protocol not available
#define EPROTONOSUPPORT 93 // Protocol not supported
#define EOPNOTSUPP 95 // Operation not supported on transport endpoint
#define EAFNOSUPPORT 97 // Address family not supported by protocol
#define EADDRINUSE 98 // Address already in use
#define EADDRNOTAVAIL 99 // Cannot assign requested address
#define ENETDOWN 100 // Network is down
#define ENETUNREACH 101 // Network is unreachable
#define ENETRESET 102 // Network dropped connection because of reset
#define ECONNABORTED 103 // Software caused connection abort
#define ECONNRESET 104 // Connection reset by peer
#define ENOBUFS 105 // No buffer space available
#define EISCONN 106 // Transport endpoint is already connected
#define ENOTCONN 107 // Transport endpoint is not connected
#define ETIMEDOUT 110 // Connection timed out
#define ECONNREFUSED 111 // Connection refused
#define EHOSTUNREACH 113 // No route to host
#define EALREADY 114 // Operation already in progress
#define EINPROGRESS 115 // Operation now in progress
#define ESTALE 116 // Reserved
#define EDQUOT 122 // Reserved
#define ECANCELED 125 // Operation Canceled
//
// serial port IOCTL
//

View File

@ -402,7 +402,7 @@ int pthread_mutex_timedlock(pthread_mutex_t* UNUSED(m), const struct timespec* U
//////////////////////////////////////////////////////////////////////////////
HANDLE sem_t_to_HANDLE(sem_t* sem)
static HANDLE HANDLE_from_sem_t(sem_t* sem)
{
return (HANDLE)*sem;
}
@ -411,28 +411,32 @@ int sem_init(sem_t* sem, int pshared, unsigned value)
{
SECURITY_ATTRIBUTES sec = { sizeof(SECURITY_ATTRIBUTES) };
sec.bInheritHandle = (BOOL)pshared;
*sem = (uintptr_t)CreateSemaphore(&sec, (LONG)value, 0x7fffffff, 0);
HANDLE h = CreateSemaphore(&sec, (LONG)value, 0x7fffffff, 0);
WARN_IF_FALSE(h);
*sem = (uintptr_t)h;
return 0;
}
int sem_post(sem_t* sem)
{
HANDLE h = sem_t_to_HANDLE(sem);
ReleaseSemaphore(h, 1, 0);
HANDLE h = HANDLE_from_sem_t(sem);
WARN_IF_FALSE(ReleaseSemaphore(h, 1, 0));
return 0;
}
int sem_wait(sem_t* sem)
{
HANDLE h = sem_t_to_HANDLE(sem);
WaitForSingleObject(h, INFINITE);
HANDLE h = HANDLE_from_sem_t(sem);
DWORD ret = WaitForSingleObject(h, INFINITE);
if(ret != WAIT_OBJECT_0)
debug_warn("unexpected WaitForSingleObject return value");
return 0;
}
int sem_destroy(sem_t* sem)
{
HANDLE h = sem_t_to_HANDLE(sem);
CloseHandle(h);
HANDLE h = HANDLE_from_sem_t(sem);
WARN_IF_FALSE(CloseHandle(h));
return 0;
}
@ -485,7 +489,7 @@ int sem_timedwait(sem_t* sem, const struct timespec* abs_timeout)
bool timeout_is_valid;
DWORD timeout_ms = calc_timeout_length_ms(abs_timeout, timeout_is_valid);
HANDLE h = sem_t_to_HANDLE(sem);
HANDLE h = HANDLE_from_sem_t(sem);
DWORD ret = WaitForSingleObject(h, timeout_ms);
// successfully decremented semaphore; bail.
if(ret == WAIT_OBJECT_0)
@ -501,3 +505,40 @@ int sem_timedwait(sem_t* sem, const struct timespec* abs_timeout)
return -1;
}
// wait until semaphore is locked or a message arrives. non-portable.
//
// background: on Win32, UI threads must periodically pump messages, or
// else deadlock may result (see WaitForSingleObject docs). that entails
// avoiding any blocking functions. when event waiting is needed,
// one cheap workaround would be to time out periodically and pump messages.
// that would work, but either wastes CPU time waiting, or introduces
// message latency. to avoid this, we provide an API similar to sem_wait and
// sem_timedwait that gives MsgWaitForMultipleObjects functionality.
//
// return value: 0 if the semaphore has been locked (SUS terminology),
// -1 otherwise. errno differentiates what happened: ETIMEDOUT if a
// message arrived (this is to ease switching between message waiting and
// periodic timeout), or an error indication.
int sem_msgwait_np(sem_t* sem)
{
HANDLE h = HANDLE_from_sem_t(sem);
DWORD ret = MsgWaitForMultipleObjects(1, &h, FALSE, INFINITE, QS_ALLEVENTS);
// semaphore is signalled
if(ret == WAIT_OBJECT_0)
return 0;
// something else:
// .. message came up
if(ret == WAIT_OBJECT_0+1)
errno = ETIMEDOUT;
// .. error
else
{
errno = EINVAL;
debug_warn("unexpected MsgWaitForMultipleObjects return value");
}
return -1;
}

View File

@ -99,4 +99,20 @@ extern int sem_wait(sem_t*);
extern int sem_timedwait(sem_t*, const struct timespec*);
extern int sem_destroy(sem_t*);
// wait until semaphore is locked or a message arrives. non-portable.
//
// background: on Win32, UI threads must periodically pump messages, or
// else deadlock may result (see WaitForSingleObject docs). that entails
// avoiding any blocking functions. when event waiting is needed,
// one cheap workaround would be to time out periodically and pump messages.
// that would work, but either wastes CPU time waiting, or introduces
// message latency. to avoid this, we provide an API similar to sem_wait and
// sem_timedwait that gives MsgWaitForMultipleObjects functionality.
//
// return value: 0 if the semaphore has been locked (SUS terminology),
// -1 otherwise. errno differentiates what happened: ETIMEDOUT if a
// message arrived (this is to ease switching between message waiting and
// periodic timeout), or an error indication.
extern int sem_msgwait_np(sem_t* sem);
#endif // #ifndef WPTHREAD_H__

View File

@ -20,21 +20,6 @@
// i.e. the same error name can be used in winsock and posix
#define WSABASEERR 10000
#define EWOULDBLOCK (35)
#define ENETDOWN (50)
#define ENETUNREACH (51)
#define ENETRESET (52)
#define ENOTCONN (57)
#define ESHUTDOWN (58)
#define ENOTCONN (57)
#define ECONNABORTED (53)
#define ECONNRESET (54)
#define ETIMEDOUT (60)
#define EADDRINUSE (48)
#define EADDRNOTAVAIL (49)
#define ECONNREFUSED (61)
#define EHOSTUNREACH (65)
#define MSG_SOCKET_READY WM_USER
#endif // #if OS_WIN