/* * This function is carefully designed to work around a bug in Windows * 95's networking winsock. Please see the beginning of this file for * a complete description of the problem. */ int sysSocketClose(int fd) { if (fd > 0) { int (PASCAL FAR *closesocketfn)(); int (PASCAL FAR *wsasenddisconnectfn)(); int dynamic_ref = -1; if ((closesocketfn = sockfnptrs[FN_CLOSESOCKET]) == NULL) { initSockFnTable(); } /* At this point we are guaranteed the sockfnptrs are initialized */ sysAssert(sockfnptrs_initialized == TRUE); closesocketfn = sockfnptrs[FN_CLOSESOCKET]; sysAssert(closesocketfn != NULL); if (winsock2Available) { struct linger l; int len = sizeof(l); if (sysGetSockOpt(fd, SOL_SOCKET, SO_LINGER, (char *)&l, &len) == 0) { if (l.l_onoff == 0) { wsasenddisconnectfn = sockfnptrs[FN_WSASENDDISCONNECT]; (*wsasenddisconnectfn)(fd, NULL); } } } (void) (*closesocketfn)(fd); } return TRUE; }
int np_continue(sys_thread_t *tid) { int count, ret = 0; int err = mutexLock(&sr_lock); sysAssert(err == 0); count = --tid->suspend_count; #ifdef LOG_THREADS dprintf(2, "[Resuming fromtid = %ld, tid = %ld, pid = %d, count = %d]\n", pthread_self(), tid->sys_thread, tid->lwp_id, count); #endif if (count == 0) { if (tid->selfsuspended) { tid->selfsuspended = 0; sem_post(&tid->sem_selfsuspend); } else { sr_tid = tid; ret = pthread_kill(tid->sys_thread, sr_sigresu); } #ifdef LOG_THREADS dprintf(2, "[Resumed fromtid = %ld, pthread_kill(%ld, %d) = %d]\n", pthread_self(), tid->sys_thread, sr_sigresu, ret); #endif } else if (count < 0) { /* Ignore attempts to resume a thread that has not been suspended */ tid->suspend_count = 0; } err = mutexUnlock(&sr_lock); sysAssert(err == 0); return ret == 0 ? SYS_OK : SYS_ERR; }
static void sigMonitorNotify() { thread_t self = thr_self(); sysAssert(userSigMon.owner == self); sysAssert(userSigMon.count > 0); condvarSignal(&userSigMon.condvar); }
int sysGetSockName(int fd, struct sockaddr *name, int *namelen) { int (PASCAL FAR *getsocknamefn)(); if ((getsocknamefn = sockfnptrs[FN_GETSOCKNAME]) == NULL) { initSockFnTable(); getsocknamefn = sockfnptrs[FN_GETSOCKNAME]; } sysAssert(sockfnptrs_initialized == TRUE); sysAssert(getsocknamefn != NULL); return (*getsocknamefn)(fd, name, namelen); }
int sysConnect(int fd, struct sockaddr *name, int namelen) { int (PASCAL FAR *connectfn)(); if ((connectfn = sockfnptrs[FN_CONNECT]) == NULL) { initSockFnTable(); connectfn = sockfnptrs[FN_CONNECT]; } sysAssert(sockfnptrs_initialized == TRUE); sysAssert(connectfn != NULL); return (*connectfn)(fd, name, namelen); }
struct protoent * sysGetProtoByName(char *name) { struct protoent * (PASCAL FAR *getprotobynamefn)(); if ((getprotobynamefn = (struct protoent * (PASCAL FAR *)()) sockfnptrs[FN_GETPROTOBYNAME]) == NULL) { initSockFnTable(); getprotobynamefn = (struct protoent * (PASCAL FAR *)()) sockfnptrs[FN_GETPROTOBYNAME]; } sysAssert(sockfnptrs_initialized == TRUE); sysAssert(getprotobynamefn != NULL); return (*getprotobynamefn)(name); }
static void sigMonitorExit() { thread_t self = thr_self(); sysAssert(userSigMon.owner == self); sysAssert(userSigMon.count > 0); if (--userSigMon.count == 0) { userSigMon.owner = 0; mutex_unlock(&userSigMon.mutex); } }
int sysBind(int fd, struct sockaddr *name, int namelen) { int (PASCAL FAR *bindfn)(); if ((bindfn = sockfnptrs[FN_BIND]) == NULL) { initSockFnTable(); bindfn = sockfnptrs[FN_BIND]; } sysAssert(sockfnptrs_initialized == TRUE); sysAssert(bindfn != NULL); return (*bindfn)(fd, name, namelen); }
int np_suspend(sys_thread_t *tid) { int count, ret = 0; int err = mutexLock(&sr_lock); sysAssert(err == 0); tid->selfsuspended = (tid == sysThreadSelf()); count = tid->suspend_count++; #ifdef LOG_THREADS dprintf(2, "[Suspending fromtid = %ld, tid = %ld, pid = %d, count = %d]\n", pthread_self(), tid->sys_thread, tid->lwp_id, count); #endif if (count == 0) { if (tid->selfsuspended) { #ifdef LOG_THREADS dprintf(2, "[Self-suspending [tid = %ld, sys_thread = %ld]\n", pthread_self(), tid->sys_thread); #endif mutexUnlock(&sr_lock); do { sem_wait(&tid->sem_selfsuspend); } while (tid->selfsuspended); /* [jk] What is the correct return value here? There was no error, but when we return the thread has already been resumed. */ return SYS_OK; } else { sr_tid = tid; ret = pthread_kill(tid->sys_thread, sr_sigsusp); if (ret == 0) { sem_wait(&sr_sem); } #ifdef LOG_THREADS dprintf(2, "[Suspended fromtid = %ld, pthread_kill(%ld, %d) = %d]\n", pthread_self(), tid->sys_thread, sr_sigsusp, ret); #endif } } err = mutexUnlock(&sr_lock); sysAssert(err == 0); return ret == 0 ? SYS_OK : SYS_ERR; }
/* * Go into single threaded mode for GC. */ int np_single() { sys_thread_t *tid; pthread_t me = pthread_self(); int i; #ifdef LOG_THREADS dprintf(2, "[Entering np_single: thread count = %d]\n", ActiveThreadCount); #endif /* Stop all other threads. */ tid = ThreadQueue; for (i = 0; i < ActiveThreadCount && tid != 0; i++) { if ((tid->sys_thread != me) && (tid->state != SUSPENDED)) { np_suspend(tid); sysAssert(VALID_SP(tid->sp, tid->stack_bottom, tid->stack_top)); tid->onproc = FALSE; /* REMIND: Might not need this */ } tid = tid->next; } #ifdef LOG_THREADS dprintf(2, "[Leaving np_single]\n"); #endif return SYS_OK; }
/* * Free any system-dependent resources held by monitors. There is * nothing to be done for native Solaris mutexes or condition variables. */ int sysMonitorDestroy(sys_mon_t *mid) { sysAssert(mid != SYS_MID_NULL); return SYS_OK; }
/* * Return true if we currently own this monitor (and threads have been * initialized. */ bool_t sysMonitorEntered(sys_thread_t *self, sys_mon_t *mid) { sysAssert(mid != SYS_MID_NULL); /* We can only have locked monitors if threads have been initialized */ return (mid->monitor_owner == self); }
int sysMonitorWait(sys_thread_t *self, sys_mon_t *mid, jlong millis) { int ret = SYS_OK; monitor_waiter_t me; sysAssert(mid != SYS_MID_NULL); if (self != mid->monitor_owner) { return SYS_ERR; } if (sysThreadIsInterrupted(self, TRUE)) { return SYS_INTRPT; } /* Prepare to wait: drop mutex ownership */ sysAssert(self->monitor_entry_count == 0); sysAssert(self->mon_wait == 0); self->mon_wait = (sys_mon_t *) mid; self->monitor_entry_count = mid->entry_count; mid->entry_count = 0; mid->monitor_owner = SYS_THREAD_NULL; /* Add myself to the monitor waitq */ enqueue_me(&me, &mid->mwait_queue, self); if (millis == SYS_TIMEOUT_INFINITY) { ret = condvarWait(&mid->cv_monitor, &mid->mutex, CONDVAR_WAIT); } else { ret = condvarTimedWait(&mid->cv_monitor, &mid->mutex, millis, CONDVAR_WAIT); } dequeue_me(&me, &mid->mwait_queue); sysAssert(mid->monitor_owner == NULL); sysAssert(mid->entry_count == 0); mid->monitor_owner = self; mid->entry_count = self->monitor_entry_count; self->monitor_entry_count = 0; self->mon_wait = 0; /* Did we get interrupted in mid-wait? (IS THIS THE RIGHT PLACE?) */ if (sysThreadIsInterrupted(self, TRUE)) { return SYS_INTRPT; } return ret; }
struct hostent * sysGetHostByAddr(const char *hostname, int len, int type) { struct hostent * (PASCAL FAR *fn)(); if ((fn = (struct hostent * (PASCAL FAR *)()) sockfnptrs[FN_GETHOSTBYADDR]) == NULL) { initSockFnTable(); fn = (struct hostent * (PASCAL FAR *)()) sockfnptrs[FN_GETHOSTBYADDR]; } sysAssert(sockfnptrs_initialized == TRUE && fn != NULL); return (*fn)(hostname, len, type); }
int sysAccept(int fd, struct sockaddr *name, int *namelen) { int (PASCAL FAR *acceptfn)(); if ((acceptfn = sockfnptrs[FN_ACCEPT]) == NULL) { initSockFnTable(); acceptfn = sockfnptrs[FN_ACCEPT]; } sysAssert(sockfnptrs_initialized == TRUE && acceptfn != NULL); return (*acceptfn)(fd, name, namelen); }
int sysRecv(int fd, char *buf, int nBytes, int flags) { int (PASCAL FAR *recvfn)(); if ((recvfn = sockfnptrs[FN_RECV]) == NULL) { initSockFnTable(); recvfn = sockfnptrs[FN_RECV]; } sysAssert(sockfnptrs_initialized == TRUE && recvfn != NULL); return (*recvfn)(fd, buf, nBytes, flags); }
int sysSend(int fd, char *buf, int nBytes, int flags) { int (PASCAL FAR *sendfn)(); if ((sendfn = sockfnptrs[FN_SEND]) == NULL) { initSockFnTable(); sendfn = sockfnptrs[FN_SEND]; } sysAssert(sockfnptrs_initialized == TRUE && sendfn != NULL); return (*sendfn)(fd, buf, nBytes, flags); }
int sysGetHostName(char *hostname, int namelen) { int (PASCAL FAR *fn)(); if ((fn = sockfnptrs[FN_GETHOSTNAME]) == NULL) { initSockFnTable(); fn = sockfnptrs[FN_GETHOSTNAME]; } sysAssert(sockfnptrs_initialized == TRUE && fn != NULL); return (*fn)(hostname, namelen); }
struct hostent * sysGetHostByName(char *hostname) { struct hostent * (PASCAL FAR *fn)(); if ((fn = (struct hostent * (PASCAL FAR *)()) sockfnptrs[FN_GETHOSTBYNAME]) == NULL) { initSockFnTable(); fn = (struct hostent * (PASCAL FAR *)()) sockfnptrs[FN_GETHOSTBYNAME]; } sysAssert(sockfnptrs_initialized == TRUE && fn != NULL); return (*fn)(hostname); }
int sysGetSockOpt(int fd, int level, int optname, char *optval, int *optlen ) { int (PASCAL FAR *getsockoptfn)(); if ((getsockoptfn = sockfnptrs[FN_GETSOCKOPT]) == NULL) { initSockFnTable(); getsockoptfn = sockfnptrs[FN_GETSOCKOPT]; } sysAssert(sockfnptrs_initialized == TRUE); sysAssert(getsockoptfn != NULL); /* We need the following translation in order to deal with the multiple definitions for IPPROTO_IP level options in different winsock versions */ if (winsock2Available && level == IPPROTO_IP && optname >= IP_OPTIONS && optname <= IP_DONTFRAGMENT) { optname = IPPROTO_OPTIONS[optname]; } return (*getsockoptfn)(fd, level, optname, optval, optlen); }
/* * If we get a nonnull function pointer it might still be the case * that some other thread is in the process of initializing the socket * function pointer table, but our pointer should still be good. */ int sysListen(int fd, int count) { int (PASCAL FAR *listenfn)(); if ((listenfn = sockfnptrs[FN_LISTEN]) == NULL) { initSockFnTable(); listenfn = sockfnptrs[FN_LISTEN]; } sysAssert(sockfnptrs_initialized == TRUE && listenfn != NULL); return (*listenfn)(fd, (long)count); }
int sysSendTo(int fd, char *buf, int len, int flags, struct sockaddr *to, int tolen) { int (PASCAL FAR *sendtofn)(); if ((sendtofn = sockfnptrs[FN_SENDTO]) == NULL) { initSockFnTable(); sendtofn = sockfnptrs[FN_SENDTO]; } sysAssert(sockfnptrs_initialized == TRUE && sendtofn != NULL); return (*sendtofn)(fd, buf, len, flags, to, tolen); }
int sysRecvFrom(int fd, char *buf, int nBytes, int flags, struct sockaddr *from, int *fromlen) { int (PASCAL FAR *recvfromfn)(); if ((recvfromfn = sockfnptrs[FN_RECVFROM]) == NULL) { initSockFnTable(); recvfromfn = sockfnptrs[FN_RECVFROM]; } sysAssert(sockfnptrs_initialized == TRUE && recvfromfn != NULL); return (*recvfromfn)(fd, buf, nBytes, flags, from, fromlen); }
long sysSocketAvailable(int fd, jint *pbytes) { int (PASCAL FAR *socketfn)(); if ((socketfn = sockfnptrs[FN_SOCKETAVAILABLE]) == NULL) { initSockFnTable(); socketfn = sockfnptrs[FN_SOCKETAVAILABLE]; } sysAssert(sockfnptrs_initialized == TRUE && socketfn != NULL); return (*socketfn)(fd, FIONREAD, pbytes); }
static void sigMonitorWait() { thread_t self = thr_self(); unsigned int saved_count = userSigMon.count; sysAssert(userSigMon.owner == self); sysAssert(userSigMon.count > 0); userSigMon.count = 0; userSigMon.owner = 0; condvarWait(&userSigMon.condvar, &userSigMon.mutex, CONDVAR_WAIT); sysAssert(userSigMon.owner == 0); sysAssert(userSigMon.count == 0); userSigMon.count = saved_count; userSigMon.owner = self; }
int sysMonitorEnter(sys_thread_t *self, sys_mon_t *mid) { int err; sysAssert(mid != SYS_MID_NULL); err = mutex_trylock(&mid->mutex); if (err == 0) { /* no one owns it */ mid->monitor_owner = self; mid->entry_count = 1; return SYS_OK; } else if (err == EBUSY) { /* it's already locked */ if (mid->monitor_owner == self) { mid->entry_count++; return SYS_OK; } else { self->mon_enter = mid; /* block on it */ if (profiler_on) { VM_CALL(monitorContendedEnter)(self, mid); mutexLock(&contention_count_mutex); mid->contention_count++; mutexUnlock(&contention_count_mutex); } mutex_lock(&mid->mutex); mid->monitor_owner = self; mid->entry_count = 1; self->mon_enter = NULL; if (profiler_on) { mutexLock(&contention_count_mutex); mid->contention_count--; mutexUnlock(&contention_count_mutex); VM_CALL(monitorContendedEntered)(self, mid); } return SYS_OK; } } else { sysAssert(err == 0); return SYS_ERR; } }
int sysMonitorExit(sys_thread_t *self, sys_mon_t *mid) { sysAssert(mid != SYS_MID_NULL); if (mid->monitor_owner == self) { sysAssert(mid->entry_count > 0); if (--mid->entry_count == 0) { mid->monitor_owner = SYS_THREAD_NULL; if (!mid->contention_count || !profiler_on) { mutex_unlock(&mid->mutex); } else { mutex_unlock(&mid->mutex); VM_CALL(monitorContendedExit)(self, mid); } } return SYS_OK; } else { return SYS_ERR; } }
int sysMonitorNotifyAll(sys_thread_t *self, sys_mon_t *mid) { sysAssert(mid != SYS_MID_NULL); if (self == mid->monitor_owner) { if (ANY_WAITING(mid->mwait_queue)) { /* If there is someone doing a monitor wait */ condvarBroadcast(&(mid->cv_monitor)); } return SYS_OK; } else return SYS_ERR; }
int sysSocketShutdown(int fd, int how) { if (fd > 0) { int (PASCAL FAR *shutdownfn)(); if ((shutdownfn = sockfnptrs[FN_SHUTDOWN]) == NULL) { initSockFnTable(); shutdownfn = sockfnptrs[FN_SHUTDOWN]; } /* At this point we are guaranteed the sockfnptrs are initialized */ sysAssert(sockfnptrs_initialized == TRUE && shutdownfn != NULL); (void) (*shutdownfn)(fd, how); } return TRUE; }
int np_initial_suspend(sys_thread_t* tid) { int count; tid->selfsuspended = (tid == sysThreadSelf()); sysAssert(tid->selfsuspended); count = tid->suspend_count++; sysAssert(count == 0); #ifdef LOG_THREADS dprintf(2, "[Initial self-suspend [tid = %ld, sys_thread = %ld]\n", pthread_self(), tid->sys_thread); #endif /* Order should not matter but doing the post first should be faster */ sem_post(&tid->sem_suspended); do { sem_wait(&tid->sem_selfsuspend); } while (tid->selfsuspended); /* paranoid */ return 0; }