static globus_result_t globus_l_xio_win32_socket_register_write( globus_l_xio_win32_socket_t * handle, globus_i_xio_system_op_info_t * write_info) { globus_result_t result; GlobusXIOName(globus_l_xio_win32_socket_register_write); GlobusXIOSystemDebugEnterFD(handle->socket); /* I have to do this outside the lock because of lock inversion issues */ if(write_info->op && globus_xio_operation_enable_cancel( write_info->op, globus_l_xio_win32_socket_cancel_cb, write_info)) { result = GlobusXIOErrorCanceled(); goto error_cancel_enable; } win32_mutex_lock(&handle->lock); { if(write_info->state == GLOBUS_I_XIO_SYSTEM_OP_CANCELED) { result = globus_error_put(write_info->error); goto error_canceled; } if(handle->write_info) { result = GlobusXIOErrorAlreadyRegistered(); goto error_already_registered; } write_info->state = GLOBUS_I_XIO_SYSTEM_OP_PENDING; /* if select() functionality requested, only handle after we receive * write event * * also dont call for connect operations. waitforbytes == 0 in this * case and handle->ready_events should not yet have a write event */ if(write_info->waitforbytes > 0 || handle->ready_events & FD_WRITE) { globus_l_xio_win32_socket_handle_write(handle, write_info); } if(write_info->state != GLOBUS_I_XIO_SYSTEM_OP_COMPLETE) { /* make sure we're set up to be notified of events */ long needevents; if(write_info->type == GLOBUS_I_XIO_SYSTEM_OP_CONNECT) { needevents = FD_CONNECT|FD_CLOSE; } else { needevents = FD_WRITE|FD_CLOSE; } if((handle->eventselect & needevents) != needevents) { if(WSAEventSelect( handle->socket, handle->event, handle->eventselect|needevents) == SOCKET_ERROR) { write_info->error = GlobusXIOErrorObjSystemError( "WSAEventSelect", WSAGetLastError()); } else { handle->eventselect |= needevents; } } if(!write_info->error) { handle->write_info = write_info; write_info = 0; } } } win32_mutex_unlock(&handle->lock); /* do this outside the lock to avoid unnecessary contention */ if(write_info) { globus_l_xio_win32_socket_complete(write_info, GLOBUS_FALSE); } GlobusXIOSystemDebugExitFD(handle->socket); return GLOBUS_SUCCESS; error_already_registered: error_canceled: write_info->state = GLOBUS_I_XIO_SYSTEM_OP_COMPLETE; win32_mutex_unlock(&handle->lock); if(write_info->op) { globus_xio_operation_disable_cancel(write_info->op); } error_cancel_enable: GlobusXIOSystemDebugExitWithErrorFD(handle->socket); return result; }
/** * Called with mutex locked */ globus_result_t globus_i_xio_http_set_end_of_entity( globus_i_xio_http_handle_t * http_handle) { globus_result_t result = GLOBUS_SUCCESS; globus_i_xio_http_header_info_t * headers; static globus_xio_iovec_t end_of_body_iovec = { "0\r\n\r\n", 5 }; GlobusXIOName(globus_i_xio_http_set_end_of_entity); if (http_handle->write_operation.operation != NULL) { result = GlobusXIOErrorAlreadyRegistered(); goto error_exit; } else if (http_handle->target_info.is_client) { headers = &http_handle->request_info.headers; } else { headers = &http_handle->response_info.headers; } if (http_handle->send_state == GLOBUS_XIO_HTTP_STATUS_LINE) { /* To send an empty response from server */ result = globus_i_xio_http_server_write_response( http_handle, NULL, 0, NULL); } else if (http_handle->send_state == GLOBUS_XIO_HTTP_CHUNK_BODY) { result = globus_xio_driver_operation_create( &http_handle->write_operation.operation, http_handle->handle); if (result != GLOBUS_SUCCESS) { goto error_exit; } result = globus_xio_driver_pass_write( http_handle->write_operation.operation, &end_of_body_iovec, 1, 5, globus_l_xio_http_write_eof_callback, http_handle); if (result != GLOBUS_SUCCESS) { globus_xio_driver_operation_destroy( http_handle->write_operation.operation); } else { http_handle->send_state = GLOBUS_XIO_HTTP_EOF; } } error_exit: return result; }