gpointer InterlockedCompareExchangePointer(volatile gpointer *dest, gpointer exch, gpointer comp) { gpointer old; int ret; mono_once(&spin_once, spin_init); pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock, (void *)&spin); ret = pthread_mutex_lock(&spin); g_assert (ret == 0); old= *dest; if(old==comp) { *dest=exch; } ret = pthread_mutex_unlock(&spin); g_assert (ret == 0); pthread_cleanup_pop (0); return(old); }
/** * InitializeCriticalSection: * @section: The critical section to initialise * * Initialises a critical section. */ void InitializeCriticalSection(WapiCriticalSection *section) { int ret; mono_once(&attr_key_once, attr_init); ret = mono_mutex_init(§ion->mutex, &attr); g_assert (ret == 0); }
/** * SetLastError: * @code: The error code. * * Sets the error code in the calling thread. */ void SetLastError(guint32 code) { int ret; /* Set the thread-local error code */ mono_once(&error_key_once, error_init); ret = pthread_setspecific(error_key, GUINT_TO_POINTER(code)); g_assert (ret == 0); }
/** * GetLastError: * * Retrieves the last error that occurred in the calling thread. * * Return value: The error code for the last error that happened on * the calling thread. */ guint32 GetLastError(void) { guint32 err; void *errptr; mono_once(&error_key_once, error_init); errptr=pthread_getspecific(error_key); err=GPOINTER_TO_UINT(errptr); return(err); }
void InterlockedWritePointer(volatile gpointer *dst, gpointer val) { int thr_ret; mono_once(&spin_once, spin_init); pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock, (void *)&spin); thr_ret = pthread_mutex_lock(&spin); g_assert (thr_ret == 0); *dst=val; thr_ret = pthread_mutex_unlock(&spin); g_assert (thr_ret == 0); pthread_cleanup_pop (0); }
gpointer InterlockedReadPointer(volatile gpointer *src) { gpointer ret; int thr_ret; mono_once(&spin_once, spin_init); pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock, (void *)&spin); thr_ret = pthread_mutex_lock(&spin); g_assert (thr_ret == 0); ret= *src; thr_ret = pthread_mutex_unlock(&spin); g_assert (thr_ret == 0); pthread_cleanup_pop (0); return(ret); }
gint32 InterlockedIncrement(volatile gint32 *dest) { gint32 ret; int thr_ret; mono_once(&spin_once, spin_init); pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock, (void *)&spin); thr_ret = pthread_mutex_lock(&spin); g_assert (thr_ret == 0); (*dest)++; ret= *dest; thr_ret = pthread_mutex_unlock(&spin); g_assert (thr_ret == 0); pthread_cleanup_pop (0); return(ret); }
gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add) { gint32 ret; int thr_ret; mono_once(&spin_once, spin_init); pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock, (void *)&spin); thr_ret = pthread_mutex_lock(&spin); g_assert (thr_ret == 0); ret= *dest; *dest+=add; thr_ret = pthread_mutex_unlock(&spin); g_assert (thr_ret == 0); pthread_cleanup_pop (0); return(ret); }
gpointer InterlockedExchangePointer(volatile gpointer *dest, gpointer exch) { gpointer ret; int thr_ret; mono_once(&spin_once, spin_init); pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock, (void *)&spin); thr_ret = pthread_mutex_lock(&spin); g_assert (thr_ret == 0); ret=*dest; *dest=exch; thr_ret = pthread_mutex_unlock(&spin); g_assert (thr_ret == 0); pthread_cleanup_pop (0); return(ret); }
gint64 InterlockedAdd64(volatile gint64 *dest, gint64 add) { gint64 ret; int thr_ret; mono_once(&spin_once, spin_init); pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock, (void *)&spin); thr_ret = pthread_mutex_lock(&spin); g_assert (thr_ret == 0); *dest += add; ret= *dest; thr_ret = pthread_mutex_unlock(&spin); g_assert (thr_ret == 0); pthread_cleanup_pop (0); return(ret); }
guint32 _wapi_socket(int domain, int type, int protocol, void *unused, guint32 unused2, guint32 unused3) { struct _WapiHandle_socket socket_handle = {0}; gpointer handle; int fd; socket_handle.domain = domain; socket_handle.type = type; socket_handle.protocol = protocol; socket_handle.still_readable = 1; fd = socket (domain, type, protocol); if (fd == -1 && domain == AF_INET && type == SOCK_RAW && protocol == 0) { /* Retry with protocol == 4 (see bug #54565) */ // https://bugzilla.novell.com/show_bug.cgi?id=MONO54565 socket_handle.protocol = 4; fd = socket (AF_INET, SOCK_RAW, 4); } if (fd == -1) { gint errnum = errno; DEBUG ("%s: socket error: %s", __func__, strerror (errno)); errnum = errno_to_WSA (errnum, __func__); WSASetLastError (errnum); return(INVALID_SOCKET); } if (fd >= _wapi_fd_reserve) { DEBUG ("%s: File descriptor is too big (%d >= %d)", __func__, fd, _wapi_fd_reserve); WSASetLastError (WSASYSCALLFAILURE); close (fd); return(INVALID_SOCKET); } /* .net seems to set this by default for SOCK_STREAM, not for * SOCK_DGRAM (see bug #36322) * https://bugzilla.novell.com/show_bug.cgi?id=MONO36322 * * It seems winsock has a rather different idea of what * SO_REUSEADDR means. If it's set, then a new socket can be * bound over an existing listening socket. There's a new * windows-specific option called SO_EXCLUSIVEADDRUSE but * using that means the socket MUST be closed properly, or a * denial of service can occur. Luckily for us, winsock * behaves as though any other system would when SO_REUSEADDR * is true, so we don't need to do anything else here. See * bug 53992. * https://bugzilla.novell.com/show_bug.cgi?id=MONO53992 */ { int ret, true = 1; ret = setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &true, sizeof (true)); if (ret == -1) { int errnum = errno; DEBUG ("%s: Error setting SO_REUSEADDR", __func__); errnum = errno_to_WSA (errnum, __func__); WSASetLastError (errnum); close (fd); return(INVALID_SOCKET); } } mono_once (&socket_ops_once, socket_ops_init); handle = _wapi_handle_new_fd (WAPI_HANDLE_SOCKET, fd, &socket_handle); if (handle == _WAPI_HANDLE_INVALID) { g_warning ("%s: error creating socket handle", __func__); WSASetLastError (WSASYSCALLFAILURE); close (fd); return(INVALID_SOCKET); } DEBUG ("%s: returning socket handle %p", __func__, handle); return(fd); }