globus_result_t globus_i_xio_system_file_try_write( globus_xio_system_file_t handle, const globus_xio_iovec_t * iov, int iovc, globus_size_t * nbytes) { globus_result_t result; GlobusXIOName(globus_i_xio_system_file_try_write); GlobusXIOSystemDebugEnter(); if(iovc == 1) { result = globus_i_xio_system_try_write( handle, iov->iov_base, iov->iov_len, nbytes); } else { result = globus_i_xio_system_try_writev(handle, iov, iovc, nbytes); } GlobusXIOSystemDebugExit(); return result; }
globus_result_t globus_xio_system_socket_create( globus_xio_system_socket_t * sock, int domain, int type, int protocol) { globus_result_t result; GlobusXIOName(globus_xio_system_socket_create); *sock = INVALID_SOCKET; GlobusXIOSystemDebugEnter(); *sock = socket(domain, type, protocol); if(*sock == INVALID_SOCKET) { result = GlobusXIOErrorSystemError("socket", WSAGetLastError()); goto error_socket; } /* all handles created by me are closed on exec */ SetHandleInformation((HANDLE)*sock, HANDLE_FLAG_INHERIT, 0); GlobusXIOSystemDebugExitFD(*sock); return GLOBUS_SUCCESS; error_socket: GlobusXIOSystemDebugExitWithErrorFD(*sock); return result; }
globus_result_t globus_i_xio_win32_complete( globus_callback_func_t callback, void * user_arg) { globus_l_xio_win32_poll_entry_t * entry; globus_result_t result; GlobusXIOName(globus_i_xio_win32_complete); GlobusXIOSystemDebugEnter(); if (! globus_i_am_only_thread()) { return globus_callback_register_oneshot( 0, 0, callback, user_arg); } win32_mutex_lock(&globus_l_xio_win32_poll_lock); { if(globus_l_xio_win32_poll_free) { entry = globus_l_xio_win32_poll_free; globus_l_xio_win32_poll_free = entry->next; } else { entry = (globus_l_xio_win32_poll_entry_t *) globus_malloc(sizeof(globus_l_xio_win32_poll_entry_t)); if(!entry) { result = GlobusXIOErrorMemory("entry"); goto error_malloc; } } entry->callback = callback; entry->user_arg = user_arg; GlobusLWin32PollQueueEnqueue(entry); if(globus_l_xio_win32_poll_event_sleeping && !globus_l_xio_win32_poll_event_pending) { SetEvent(globus_l_xio_win32_poll_event); globus_l_xio_win32_poll_event_pending = GLOBUS_TRUE; } } win32_mutex_unlock(&globus_l_xio_win32_poll_lock); GlobusXIOSystemDebugExit(); return GLOBUS_SUCCESS; error_malloc: return result; }
globus_result_t globus_i_xio_system_socket_try_write( globus_xio_system_socket_t handle, const globus_xio_iovec_t * iov, int iovc, int flags, globus_sockaddr_t * to, globus_size_t * nbytes) { globus_result_t result; GlobusXIOName(globus_i_xio_system_socket_try_write); GlobusXIOSystemDebugEnter(); #if !defined(WIN32) && !defined(TARGET_ARCH_NETOS) /* posix can use writev for sockets */ if(!flags && !to && iovc > 1) { result = globus_i_xio_system_try_writev(handle, iov, iovc, nbytes); } else #endif if(iovc == 1) { if(to) { result = globus_i_xio_system_try_sendto( handle, iov->iov_base, iov->iov_len, flags, to, nbytes); } else { result = globus_i_xio_system_try_send( handle, iov->iov_base, iov->iov_len, flags, nbytes); } } else { struct msghdr msghdr; memset(&msghdr, 0, sizeof(msghdr)); msghdr.msg_iov = (struct iovec *) iov; msghdr.msg_iovlen = iovc; if(to) { msghdr.msg_name = (struct sockaddr *) to; msghdr.msg_namelen = GlobusLibcSockaddrLen(to); } result = globus_i_xio_system_try_sendmsg( handle, &msghdr, flags, nbytes); } GlobusXIOSystemDebugExit(); return result; }
globus_result_t globus_i_xio_system_socket_try_read( globus_xio_system_socket_t handle, const globus_xio_iovec_t * iov, int iovc, int flags, globus_sockaddr_t * from, globus_size_t * nbytes) { globus_result_t result; GlobusXIOName(globus_i_xio_system_socket_try_read); GlobusXIOSystemDebugEnter(); #if !defined(WIN32) && !defined(TARGET_ARCH_NETOS) /* posix can use readv for sockets */ if(!flags && !from && iovc > 1) { result = globus_i_xio_system_try_readv(handle, iov, iovc, nbytes); } else #endif if(iovc == 1) { if(from) { result = globus_i_xio_system_try_recvfrom( handle, iov->iov_base, iov->iov_len, flags, from, nbytes); } else { result = globus_i_xio_system_try_recv( handle, iov->iov_base, iov->iov_len, flags, nbytes); } } else { struct msghdr msghdr; memset(&msghdr, 0, sizeof(msghdr)); msghdr.msg_iov = (struct iovec *) iov; msghdr.msg_iovlen = iovc; if(from) { msghdr.msg_name = from; msghdr.msg_namelen = sizeof(globus_sockaddr_t); } result = globus_i_xio_system_try_recvmsg( handle, &msghdr, flags, nbytes); } GlobusXIOSystemDebugExit(); return result; }
int globus_i_xio_win32_complete_activate(void) { globus_result_t result; globus_reltime_t period; GlobusXIOName(globus_i_xio_win32_complete_activate); GlobusXIOSystemDebugEnter(); if (!globus_i_am_only_thread()) { goto skip_activate; } GlobusLWin32PollQueueInit(); win32_mutex_init(&globus_l_xio_win32_poll_lock, 0); globus_l_xio_win32_poll_event_sleeping = GLOBUS_FALSE; globus_l_xio_win32_poll_event_pending = GLOBUS_FALSE; globus_l_xio_win32_poll_free = 0; globus_l_xio_win32_poll_event = CreateEvent(0, FALSE, FALSE, 0); if(globus_l_xio_win32_poll_event == 0) { goto error_event; } GlobusTimeReltimeSet(period, 0, 0); result = globus_callback_register_periodic( &globus_l_xio_win32_poll_handle, 0, &period, globus_l_xio_win32_poll, 0); if(result != GLOBUS_SUCCESS) { goto error_periodic; } globus_callback_add_wakeup_handler( globus_l_xio_win32_wakeup_handler, 0); skip_activate: GlobusXIOSystemDebugExit(); return GLOBUS_SUCCESS; error_periodic: CloseHandle(globus_l_xio_win32_poll_event); globus_l_xio_win32_poll_event = 0; error_event: win32_mutex_destroy(&globus_l_xio_win32_poll_lock); GlobusXIOSystemDebugExitWithError(); return GLOBUS_FAILURE; }
int globus_i_xio_system_common_deactivate(void) { GlobusXIOName(globus_i_xio_system_common_deactivate); GlobusXIOSystemDebugEnter(); globus_module_deactivate(GLOBUS_XIO_MODULE); GlobusXIOSystemDebugExit(); GlobusDebugDestroy(GLOBUS_XIO_SYSTEM); return GLOBUS_SUCCESS; }
static void globus_l_xio_win32_blocking_destroy( globus_l_xio_win32_blocking_info_t * blocking_info) { GlobusXIOName(globus_l_xio_win32_blocking_destroy); GlobusXIOSystemDebugEnter(); WSACloseEvent(blocking_info->event); globus_free(blocking_info); GlobusXIOSystemDebugExit(); }
static void globus_l_xio_win32_wakeup_handler( void * user_arg) { GlobusXIOName(globus_l_xio_win32_wakeup_handler); GlobusXIOSystemDebugEnter(); if(globus_l_xio_win32_poll_event != 0) { SetEvent(globus_l_xio_win32_poll_event); } GlobusXIOSystemDebugExit(); }
static void globus_l_xio_win32_blocking_cb( globus_result_t result, globus_size_t nbytes, void * user_arg) { globus_l_xio_win32_blocking_info_t * blocking_info; GlobusXIOName(globus_l_xio_win32_blocking_cb); GlobusXIOSystemDebugEnter(); blocking_info = (globus_l_xio_win32_blocking_info_t *) user_arg; if(result != GLOBUS_SUCCESS) { blocking_info->error = globus_error_get(result); } blocking_info->nbytes = nbytes; SetEvent(blocking_info->event); GlobusXIOSystemDebugExit(); }
static globus_result_t globus_l_xio_win32_blocking_init( globus_l_xio_win32_blocking_info_t ** u_blocking_info) { globus_l_xio_win32_blocking_info_t * blocking_info; globus_result_t result; GlobusXIOName(globus_l_xio_win32_blocking_init); GlobusXIOSystemDebugEnter(); blocking_info = (globus_l_xio_win32_blocking_info_t *) globus_calloc(1, sizeof(globus_l_xio_win32_blocking_info_t)); if(!blocking_info) { result = GlobusXIOErrorMemory("blocking_info"); goto error_info; } blocking_info->event = CreateEvent(0, FALSE, FALSE, 0); if(blocking_info->event == 0) { result = GlobusXIOErrorSystemError( "CreateEvent", GetLastError()); goto error_create; } *u_blocking_info = blocking_info; GlobusXIOSystemDebugExit(); return GLOBUS_SUCCESS; error_create: globus_free(blocking_info); error_info: *u_blocking_info = 0; GlobusXIOSystemDebugExitWithError(); return result; }
static void globus_l_xio_win32_unregister_poll_cb( void * user_arg) { globus_l_shutdown_info_t * info; GlobusXIOName(globus_l_xio_win32_unregister_poll_cb); GlobusXIOSystemDebugEnter(); info = (globus_l_shutdown_info_t *) user_arg; globus_mutex_lock(&info->mutex); { CloseHandle(globus_l_xio_win32_poll_event); globus_l_xio_win32_poll_event = 0; globus_cond_signal(&info->cond); } globus_mutex_unlock(&info->mutex); GlobusXIOSystemDebugExit(); }
static void globus_l_xio_win32_socket_cancel_cb( globus_xio_operation_t op, void * user_arg, globus_xio_error_type_t reason) { globus_i_xio_system_op_info_t * op_info; GlobusXIOName(globus_l_xio_win32_socket_cancel_cb); GlobusXIOSystemDebugEnter(); op_info = (globus_i_xio_system_op_info_t *) user_arg; /* this access of the handle is not safe if users destroy it * with outstanding callbacks. I don't think that is allowed, so we * should be ok. */ win32_mutex_lock(&op_info->handle->lock); { if(op_info->state != GLOBUS_I_XIO_SYSTEM_OP_COMPLETE && op_info->state != GLOBUS_I_XIO_SYSTEM_OP_CANCELED) { op_info->error = reason == GLOBUS_XIO_ERROR_TIMEOUT ? GlobusXIOErrorObjTimeout() : GlobusXIOErrorObjCanceled(); if(op_info->state == GLOBUS_I_XIO_SYSTEM_OP_NEW) { op_info->state = GLOBUS_I_XIO_SYSTEM_OP_CANCELED; GlobusXIOSystemDebugPrintf( GLOBUS_I_XIO_SYSTEM_DEBUG_INFO, ("[%s] fd=%lu, Canceling NEW\n", _xio_name, (unsigned long)op_info->handle->socket)); } else { globus_result_t result; op_info->state = GLOBUS_I_XIO_SYSTEM_OP_COMPLETE; GlobusXIOSystemDebugPrintf( GLOBUS_I_XIO_SYSTEM_DEBUG_INFO, ("[%s] fd=%lu, Canceling Pending\n", _xio_name, (unsigned long)op_info->handle->socket)); if(op_info->handle->read_info == op_info) { op_info->handle->read_info = 0; } else { globus_assert(op_info->handle->write_info == op_info); op_info->handle->write_info = 0; } /* unregister and kickout now */ result = globus_callback_register_oneshot( 0, 0, globus_l_xio_win32_socket_kickout, op_info); /* really cant do anything else */ if(result != GLOBUS_SUCCESS) { globus_panic( GLOBUS_XIO_SYSTEM_MODULE, result, _XIOSL("[%s:%d] Couldn't register callback"), _xio_name, __LINE__); } } } } win32_mutex_unlock(&op_info->handle->lock); GlobusXIOSystemDebugExit(); }
int globus_i_xio_system_common_activate(void) { GlobusXIOName(globus_i_xio_system_common_activate); GlobusDebugInit(GLOBUS_XIO_SYSTEM, TRACE DATA INFO RAW); GlobusXIOSystemDebugEnter(); /* I am going to leave this memory around after deactivation. To safely * destroy them, I would need a lot more synchronization of kicked out * callbacks */ if(globus_module_activate(GLOBUS_XIO_MODULE) != GLOBUS_SUCCESS) { goto error_activate; } if(!globus_l_xio_system_memory_initialized) { globus_l_xio_system_memory_initialized = GLOBUS_TRUE; globus_memory_init( &globus_i_xio_system_op_info_memory, sizeof(globus_i_xio_system_op_info_t), 10); globus_memory_init( &globus_i_xio_system_iov_memory, sizeof(struct iovec) * 10, 10); } globus_l_xio_iov_max = -1; #ifdef _SC_IOV_MAX if (globus_l_xio_iov_max == -1) { /* If this returns -1, the limit might be indefinite if errno is * unchanged, but that doesn't mean infinite. It's unclear what * one is to do in that case */ globus_l_xio_iov_max = sysconf(_SC_IOV_MAX); } #endif #ifdef IOV_MAX if (globus_l_xio_iov_max == -1) { globus_l_xio_iov_max = IOV_MAX; } #endif #ifdef _XOPEN_IOV_MAX if (globus_l_xio_iov_max == -1) { globus_l_xio_iov_max = _XOPEN_IOV_MAX; } #endif if (globus_l_xio_iov_max == -1) { globus_l_xio_iov_max = 16; } GlobusXIOSystemDebugExit(); return GLOBUS_SUCCESS; error_activate: GlobusXIOSystemDebugExitWithError(); GlobusDebugDestroy(GLOBUS_XIO_SYSTEM); return GLOBUS_FAILURE; }
static void globus_l_xio_win32_poll( void * user_arg) { GlobusXIOName(globus_l_xio_win32_poll); GlobusXIOSystemDebugEnter(); win32_mutex_lock(&globus_l_xio_win32_poll_lock); { if(GlobusLWin32PollQueueEmpty()) { globus_reltime_t time_left; globus_callback_get_timeout(&time_left); if(globus_reltime_cmp(&time_left, &globus_i_reltime_zero) > 0) { DWORD millis = INFINITE; if(!globus_time_reltime_is_infinity(&time_left)) { GlobusTimeReltimeToMilliSec(millis, time_left); } globus_l_xio_win32_poll_event_sleeping = GLOBUS_TRUE; win32_mutex_unlock(&globus_l_xio_win32_poll_lock); WaitForSingleObject(globus_l_xio_win32_poll_event, millis); win32_mutex_lock(&globus_l_xio_win32_poll_lock); globus_l_xio_win32_poll_event_sleeping = GLOBUS_FALSE; globus_l_xio_win32_poll_event_pending = GLOBUS_FALSE; } } while(!GlobusLWin32PollQueueEmpty()) { globus_l_xio_win32_poll_entry_t * entry; GlobusLWin32PollQueueDequeue(entry); win32_mutex_unlock(&globus_l_xio_win32_poll_lock); entry->callback(entry->user_arg); win32_mutex_lock(&globus_l_xio_win32_poll_lock); entry->next = globus_l_xio_win32_poll_free; globus_l_xio_win32_poll_free = entry; if(globus_callback_has_time_expired()) { break; } } } win32_mutex_unlock(&globus_l_xio_win32_poll_lock); GlobusXIOSystemDebugExit(); }
int globus_i_xio_win32_complete_deactivate(void) { globus_result_t result; globus_l_shutdown_info_t info; GlobusXIOName(globus_i_xio_win32_complete_deactivate); GlobusXIOSystemDebugEnter(); if (!globus_i_am_only_thread()) { goto skip_deactivate; } globus_mutex_init(&info.mutex, NULL); globus_cond_init(&info.cond, NULL); globus_mutex_lock(&info.mutex); { result = globus_callback_unregister( globus_l_xio_win32_poll_handle, globus_l_xio_win32_unregister_poll_cb, &info, 0); if(result == GLOBUS_SUCCESS) { /* unregister callback destroys this event object */ while(globus_l_xio_win32_poll_event != 0) { globus_cond_wait(&info.cond, &info.mutex); } } else { globus_mutex_unlock(&info.mutex); globus_l_xio_win32_unregister_poll_cb(&info); globus_mutex_lock(&info.mutex); } } globus_mutex_unlock(&info.mutex); globus_cond_destroy(&info.cond); globus_mutex_destroy(&info.mutex); win32_mutex_destroy(&globus_l_xio_win32_poll_lock); while(globus_l_xio_win32_poll_free) { globus_l_xio_win32_poll_entry_t * next = globus_l_xio_win32_poll_free->next; globus_free(globus_l_xio_win32_poll_free); globus_l_xio_win32_poll_free = next; } skip_deactivate: GlobusXIOSystemDebugExit(); return GLOBUS_SUCCESS; }