/* Wait for a disconnected event. * * return -1 on error */ static int psdapl_wait4event(psdapl_con_info_t *ci, unsigned ev, const char *ev_name) { DAT_EVENT event; DAT_COUNT nmore; DAT_RETURN dat_rc; dat_rc = dat_evd_wait(ci->connect_evd_handle, 3*1000*1000 /* timeout in usec */, 1 /* threshold */, &event, &nmore); switch (DAT_GET_TYPE(dat_rc)) { case DAT_TIMEOUT_EXPIRED: psdapl_dprint(2, "psdapl_wait4event(%s): DAT_TIMEOUT_EXPIRED", ev_name); return -1; break; case DAT_SUCCESS: if (event.event_number == ev) { psdapl_dprint(3, "event %s", ev_name); return 0; } else { psdapl_dprint(2, "psdapl_wait4event(%s): unexpected event 0x%x", ev_name, (unsigned)event.event_number); } break; default: psdapl_dprint_dat_err(2, dat_rc, "psdapl_wait4event(%s): dat_evd_wait()", ev_name); } return -1; }
/* read all events from recv_evd_handle */ static void psdapl_flush_evd(psdapl_con_info_t *ci) { while (1) { DAT_RETURN dat_rc; DAT_EVENT event; DAT_COUNT nmore = 0; #if 0 dat_rc = dat_evd_wait(ci->recv_evd_handle, 0 /*timeout in usec*/, 1 /* threshold */, &event, &nmore); #else dat_rc = dat_evd_dequeue(ci->recv_evd_handle, &event); nmore = 1; #endif switch (DAT_GET_TYPE(dat_rc)) { case DAT_TIMEOUT_EXPIRED: // psdapl_dprint(3, "psdapl_flush_evd event DAT_TIMEOUT_EXPIRED. nmore:%d", nmore); ci->outstanding_cq_entries = 0; psdapl_stat.timeouts++; break; case DAT_SUCCESS: switch (event.event_number) { case DAT_DTO_COMPLETION_EVENT: if (!event.event_data.dto_completion_event_data.user_cookie.as_ptr) { // From sendv if (ci->outstanding_cq_entries) { ci->outstanding_cq_entries--; } } else { do_DTO_COMPLETION_EVENT(ci, &event.event_data.dto_completion_event_data); } // psdapl_dprint(3, "psdapl_flush_evd event DAT_DTO_COMPLETION_EVENT. nmore:%d", nmore); break; default: psdapl_dprint(1, "psdapl_flush_evd: unexpected event 0x%x. nmore:%d", (unsigned)event.event_number, nmore); break; } break; case DAT_QUEUE_EMPTY: nmore = 0; break; default: nmore = 0; psdapl_dprint_dat_err(1, dat_rc, "psdapl_flush_evd: dat_evd_wait(). nmore:%d", nmore); } if (!nmore) break; } }
/* ----------------------------------------------------------- * Poll for a DTO event, returning false on error. */ bool DT_dto_event_poll(DT_Tdep_Print_Head * phead, DAT_EVD_HANDLE evd_handle, DAT_DTO_COMPLETION_EVENT_DATA * dto_statusp) { for (;;DT_Mdep_yield()) { DAT_RETURN ret; DAT_EVENT event; ret = DT_Tdep_evd_dequeue(evd_handle, &event); if (DAT_GET_TYPE(ret) == DAT_QUEUE_EMPTY) { continue; } if (ret != DAT_SUCCESS) { DT_Tdep_PT_Printf(phead, "Test Error: dapl_event_wait (DTO) failed: %s\n", DT_RetToString(ret)); DT_Test_Error(); break; } if (event.event_number == DAT_DTO_COMPLETION_EVENT) { /* * Pass back all the useful bits if requested: * ep_handle, user_cookie.as_ptr * status, transfered_length */ if (dto_statusp) { *dto_statusp = event.event_data.dto_completion_event_data; } return (true); } DT_Tdep_PT_Printf(phead, "Warning: dto_event_poll swallowing %s event\n", DT_EventToSTr(event.event_number)); } return (false); }
/* create a PSP to listen on a port. * return: DAT_CONN_QUAL (the port) in socket->listen_conn_qual and * the address in DAT_SOCK_ADDR socket->sock_addr (already set by * psdapl_socket_create() * * return -1 on error. */ int psdapl_listen(psdapl_socket_t *socket) { DAT_RETURN dat_rc; if (socket->psp_handle) return 0; /* already listening */ dat_rc = dat_evd_create(socket->ia_handle, EVD_MIN_QLEN /* ToDo: evd_min_qlen */, DAT_HANDLE_NULL, // cno_handle DAT_EVD_CR_FLAG,//DAT_EVD_DEFAULT_FLAG, &socket->evd_handle); if (dat_rc != DAT_SUCCESS) goto err_evd_create; DAT_CONN_QUAL conn_qual = getpid(); int maxcnt = 100; while (1) { dat_rc = dat_psp_create(socket->ia_handle, conn_qual, socket->evd_handle, DAT_PSP_CONSUMER_FLAG /* DAT_PSP_PROVIDER_FLAG */, &socket->psp_handle); if (dat_rc == DAT_SUCCESS) break; maxcnt--; if (!maxcnt || (DAT_GET_TYPE(dat_rc) != DAT_CONN_QUAL_IN_USE)) goto err_psp_create; conn_qual++; } socket->listen_conn_qual = conn_qual; return 0; err_psp_create: psdapl_dprint_dat_err(0, dat_rc, "dat_psp_create(conn_qual=%u) failed", (unsigned)conn_qual); return -1; err_evd_create: psdapl_dprint_dat_err(0, dat_rc, "dat_evd_create() failed"); return -1; }
/*--------------------------------------------------------*/ int DT_pz_case1(Params_t * params_ptr, FFT_Cmd_t * cmd) { char *dev_name; DAT_IA_HANDLE ia_handle; DAT_PZ_HANDLE pz_handle; DAT_EP_HANDLE ep_handle; DAT_EVD_HANDLE conn_evd, send_evd, recv_evd, cr_evd; DAT_RETURN rc; int res; DT_Tdep_Print_Head *phead; phead = params_ptr->phead; DT_Tdep_PT_Printf(phead, "\ Description: try to destroy pz with vi still associated with it\n"); res = 1; ia_handle = 0; pz_handle = 0; ep_handle = 0; conn_evd = 0; send_evd = 0; recv_evd = 0; cr_evd = 0; dev_name = cmd->device_name; rc = DT_ia_open(dev_name, &ia_handle); DT_assert_dat(phead, rc == DAT_SUCCESS); rc = dat_pz_create(ia_handle, &pz_handle); DT_assert_dat(phead, rc == DAT_SUCCESS); rc = DT_ep_create(params_ptr, ia_handle, pz_handle, &cr_evd, &conn_evd, &send_evd, &recv_evd, &ep_handle); DT_assert_dat(phead, rc == DAT_SUCCESS); if (pz_handle) { rc = dat_pz_free(pz_handle); DT_assert_dat(phead, DAT_GET_TYPE(rc) == DAT_INVALID_STATE); } cleanup: /* corrrect order */ if (ep_handle) { rc = dat_ep_free(ep_handle); DT_assert_clean(phead, rc == DAT_SUCCESS); } if (conn_evd) { rc = DT_Tdep_evd_free(conn_evd); DT_assert_clean(phead, rc == DAT_SUCCESS); } if (send_evd) { rc = DT_Tdep_evd_free(send_evd); DT_assert_clean(phead, rc == DAT_SUCCESS); } if (recv_evd) { rc = DT_Tdep_evd_free(recv_evd); DT_assert_clean(phead, rc == DAT_SUCCESS); } if (pz_handle) { rc = dat_pz_free(pz_handle); DT_assert_clean(phead, rc == DAT_SUCCESS); } if (ia_handle) { rc = dat_ia_close(ia_handle, DAT_CLOSE_ABRUPT_FLAG); DT_assert_clean(phead, rc == DAT_SUCCESS); } return res; } /*--------------------------------------------------------*/ int DT_pz_case2(Params_t * params_ptr, FFT_Cmd_t * cmd) { char *dev_name; DAT_IA_HANDLE ia_handle; DAT_PZ_HANDLE pz_handle; Bpool *bpool; DAT_RETURN rc; int res; DT_Tdep_Print_Head *phead; phead = params_ptr->phead; DT_Tdep_PT_Printf(phead, "\ Description: try to destroy pz with registered memory still\n"); DT_Tdep_PT_Printf(phead, "\ associated with it\n"); res = 1; ia_handle = 0; pz_handle = 0; bpool = 0; dev_name = cmd->device_name; rc = DT_ia_open(dev_name, &ia_handle); DT_assert_dat(phead, rc == DAT_SUCCESS); rc = dat_pz_create(ia_handle, &pz_handle); DT_assert_dat(phead, rc == DAT_SUCCESS); /* allocate and register bpool */ bpool = DT_BpoolAlloc(0, phead, ia_handle, pz_handle, NULL, NULL, BUFFSIZE, 1, DAT_OPTIMAL_ALIGNMENT, false, false); DT_assert(phead, bpool != 0); if (pz_handle) { rc = dat_pz_free(pz_handle); DT_assert_dat(phead, DAT_GET_TYPE(rc) == DAT_INVALID_STATE); } cleanup: /* deregister and free bpool */ if (DT_Bpool_Destroy(0, phead, bpool) == false) { DT_Tdep_PT_Printf(phead, "Warning: Destroy bpool fails, reboot for cleanup\n"); return 0; } if (pz_handle) { rc = dat_pz_free(pz_handle); DT_assert_clean(phead, rc == DAT_SUCCESS); } if (ia_handle) { rc = dat_ia_close(ia_handle, DAT_CLOSE_ABRUPT_FLAG); DT_assert_clean(phead, rc == DAT_SUCCESS); } return res; } /*-------------------------------------------------------------*/ void DT_pz_test(Params_t * params_ptr, FFT_Cmd_t * cmd) { int i; int res; DT_Tdep_Print_Head *phead; FFT_Testfunc_t cases_func[] = { {DT_pz_case0}, {DT_pz_case1}, {DT_pz_case2}, }; phead = params_ptr->phead; for (i = 0; i < cmd->size; i++) { if (cmd->cases_flag[i]) { DT_Tdep_PT_Printf(phead, "\ *********************************************************************\n"); DT_Tdep_PT_Printf(phead, "\ Function feature: Protection Zone management case: %d\n", i); res = cases_func[i].fun(params_ptr, cmd); if (res == 1) { DT_Tdep_PT_Printf(phead, "Result: PASS\n"); } else if (res == 0) { DT_Tdep_PT_Printf(phead, "Result: FAIL\n"); } else if (res == -1) { DT_Tdep_PT_Printf(phead, "Result: use other test tool\n"); } else if (res == -2) { DT_Tdep_PT_Printf(phead, "Result: not support or next stage to develop\n"); } DT_Tdep_PT_Printf(phead, "\ *********************************************************************\n"); } }
DAT_RETURN dat_strerror_major( IN DAT_RETURN value, OUT const char **message) { switch (DAT_GET_TYPE(value)) { case DAT_SUCCESS: { *message = "DAT_SUCCESS"; return (DAT_SUCCESS); } case DAT_ABORT: { *message = "DAT_ABORT"; return (DAT_SUCCESS); } case DAT_CONN_QUAL_IN_USE: { *message = "DAT_CONN_QUAL_IN_USE"; return (DAT_SUCCESS); } case DAT_INSUFFICIENT_RESOURCES: { *message = "DAT_INSUFFICIENT_RESOURCES"; return (DAT_SUCCESS); } case DAT_INTERNAL_ERROR: { *message = "DAT_INTERNAL_ERROR"; return (DAT_SUCCESS); } case DAT_INVALID_HANDLE: { *message = "DAT_INVALID_HANDLE"; return (DAT_SUCCESS); } case DAT_INVALID_PARAMETER: { *message = "DAT_INVALID_PARAMETER"; return (DAT_SUCCESS); } case DAT_INVALID_STATE: { *message = "DAT_INVALID_STATE"; return (DAT_SUCCESS); } case DAT_LENGTH_ERROR: { *message = "DAT_LENGTH_ERROR"; return (DAT_SUCCESS); } case DAT_MODEL_NOT_SUPPORTED: { *message = "DAT_MODEL_NOT_SUPPORTED"; return (DAT_SUCCESS); } case DAT_NAME_NOT_FOUND: { *message = "DAT_NAME_NOT_FOUND"; return (DAT_SUCCESS); } case DAT_PRIVILEGES_VIOLATION: { *message = "DAT_PRIVILEGES_VIOLATION"; return (DAT_SUCCESS); } case DAT_PROTECTION_VIOLATION: { *message = "DAT_PROTECTION_VIOLATION"; return (DAT_SUCCESS); } case DAT_QUEUE_EMPTY: { *message = "DAT_QUEUE_EMPTY"; return (DAT_SUCCESS); } case DAT_QUEUE_FULL: { *message = "DAT_QUEUE_FULL"; return (DAT_SUCCESS); } case DAT_TIMEOUT_EXPIRED: { *message = "DAT_TIMEOUT_EXPIRED"; return (DAT_SUCCESS); } case DAT_PROVIDER_ALREADY_REGISTERED: { *message = "DAT_PROVIDER_ALREADY_REGISTERED"; return (DAT_SUCCESS); } case DAT_PROVIDER_IN_USE: { *message = "DAT_PROVIDER_IN_USE"; return (DAT_SUCCESS); } case DAT_INVALID_ADDRESS: { *message = "DAT_INVALID_ADDRESS"; return (DAT_SUCCESS); } case DAT_INTERRUPTED_CALL: { *message = "DAT_INTERRUPTED_CALL"; return (DAT_SUCCESS); } case DAT_NOT_IMPLEMENTED: { *message = "DAT_NOT_IMPLEMENTED"; return (DAT_SUCCESS); } default: { return (DAT_INVALID_PARAMETER); } } }
/* * dapl_cno_wait * * DAPL Requirements Version xxx, 6.3.2.3 * * Wait for a consumer notification event * * Input: * cno_handle * timeout * evd_handle * * Output: * evd_handle * * Returns: * DAT_SUCCESS * DAT_INVALID_HANDLE * DAT_QUEUE_EMPTY * DAT_INVALID_PARAMETER */ DAT_RETURN DAT_API dapl_cno_wait(IN DAT_CNO_HANDLE cno_handle, /* cno_handle */ IN DAT_TIMEOUT timeout, /* agent */ OUT DAT_EVD_HANDLE * evd_handle) { /* ia_handle */ DAPL_CNO *cno_ptr; DAT_RETURN dat_status; if (DAPL_BAD_HANDLE(cno_handle, DAPL_MAGIC_CNO)) { dat_status = DAT_INVALID_HANDLE | DAT_INVALID_HANDLE_CNO; goto bail; } dat_status = DAT_SUCCESS; cno_ptr = (DAPL_CNO *) cno_handle; if (cno_ptr->cno_state == DAPL_CNO_STATE_DEAD) { dat_status = DAT_ERROR(DAT_INVALID_STATE, DAT_INVALID_STATE_CNO_DEAD); goto bail; } dapl_os_lock(&cno_ptr->header.lock); if (cno_ptr->cno_state == DAPL_CNO_STATE_TRIGGERED) { cno_ptr->cno_state = DAPL_CNO_STATE_UNTRIGGERED; *evd_handle = cno_ptr->cno_evd_triggered; cno_ptr->cno_evd_triggered = NULL; dapl_os_unlock(&cno_ptr->header.lock); goto bail; } while (cno_ptr->cno_state == DAPL_CNO_STATE_UNTRIGGERED && DAT_GET_TYPE(dat_status) != DAT_TIMEOUT_EXPIRED) { cno_ptr->cno_waiters++; dapl_os_unlock(&cno_ptr->header.lock); dat_status = dapl_os_wait_object_wait(&cno_ptr->cno_wait_object, timeout); dapl_os_lock(&cno_ptr->header.lock); cno_ptr->cno_waiters--; } if (cno_ptr->cno_state == DAPL_CNO_STATE_DEAD) { dat_status = DAT_ERROR(DAT_INVALID_STATE, DAT_INVALID_STATE_CNO_DEAD); } else if (dat_status == DAT_SUCCESS) { /* * After the first triggering, this will be a valid handle. * If we're racing with wakeups of other CNO waiters, * that's ok. */ dapl_os_assert(cno_ptr->cno_state == DAPL_CNO_STATE_TRIGGERED); cno_ptr->cno_state = DAPL_CNO_STATE_UNTRIGGERED; *evd_handle = cno_ptr->cno_evd_triggered; cno_ptr->cno_evd_triggered = NULL; } else if (DAT_GET_TYPE(dat_status) == DAT_TIMEOUT_EXPIRED) { cno_ptr->cno_state = DAPL_CNO_STATE_UNTRIGGERED; *evd_handle = NULL; dat_status = DAT_QUEUE_EMPTY; } else { /* * The only other reason we could have made it out of * the loop is an interrupted system call. */ dapl_os_assert(DAT_GET_TYPE(dat_status) == DAT_INTERRUPTED_CALL); } dapl_os_unlock(&cno_ptr->header.lock); bail: return dat_status; }
/* Connect a remote PSP at addr : conn_qual * return -1 on error */ int psdapl_connect(psdapl_con_info_t *ci, psdapl_info_msg_t *msg) { int rc; DAT_RETURN dat_rc; rc = psdapl_init_buffers_local(ci); if (rc) goto err_init_buf; rc = psdapl_create_ep(ci); if (rc) goto err_create_ep; psdapl_init_msg_t res_imsg; psdapl_init_init_msg(&res_imsg, ci); dat_rc = dat_ep_connect(ci->ep_handle, &msg->sock_addr, msg->conn_qual, DAT_TIMEOUT_INFINITE /* 5 * 1000 * 1000 */, sizeof(res_imsg) /* private_data_size */, &res_imsg /* private_data */, DAT_QOS_BEST_EFFORT /* DAT_QOS */, DAT_CONNECT_DEFAULT_FLAG /* DAT_CONNECT_FLAGS */); if (dat_rc != DAT_SUCCESS) goto err_ep_connect; DAT_EVENT event; DAT_COUNT nmore; event.event_number = -1; dat_rc = dat_evd_wait(ci->connect_evd_handle, DAT_TIMEOUT_INFINITE /* 5*1000*1000 timeout in usec*/, 1 /* threshold */, &event, &nmore); psdapl_init_msg_t *imsg = NULL; switch (DAT_GET_TYPE(dat_rc)) { /* case DAT_TIMEOUT_EXPIRED: fprintf(stderr, "<mark (timeout)>\n"); break; */ case DAT_SUCCESS: switch (event.event_number) { case DAT_CONNECTION_EVENT_TIMED_OUT: psdapl_dprint(2, "psdapl_connect: event DAT_CONNECTION_EVENT_TIMED_OUT"); break; case DAT_CONNECTION_EVENT_ESTABLISHED: psdapl_dprint(3, "psdapl_connect: event DAT_CONNECTION_EVENT_ESTABLISHED"); DAT_CONNECTION_EVENT_DATA *cd = &event.event_data.connect_event_data; imsg = (psdapl_init_msg_t *)(cd->private_data); break; default: psdapl_dprint(2, "psdapl_connect: unexpected event 0x%x", (unsigned)event.event_number); break; } break; default: psdapl_dprint_dat_err(1, dat_rc, "psdapl_connect: dat_evd_wait()"); break; } if (!imsg) goto err_wait; psdapl_init_buffers_remote(ci, imsg); return 0; /* --- */ err_ep_connect: psdapl_dprint_dat_err(0, dat_rc, "dat_ep_connect() failed"); goto err_all; /* --- */ err_all: err_wait: err_create_ep: err_init_buf: /* ToDo: Cleanup recv_evd_handle!! */ /* ToDo: Cleanup connect_evd_handle!! */ /* ToDo: Cleanup bufpairs!!!!! */ return -1; }
/* Wait for a new connection on the PSP (psdapl_listen()). * * return -1 on error */ int psdapl_accept_wait(psdapl_con_info_t *ci) { DAT_EVENT event; DAT_COUNT nmore; DAT_RETURN dat_rc; dat_rc = dat_evd_wait(ci->socket->evd_handle, DAT_TIMEOUT_INFINITE /* 5*1000*1000 timeout in usec*/, 1 /* threshold */, &event, &nmore); switch (DAT_GET_TYPE(dat_rc)) { /* case DAT_TIMEOUT_EXPIRED: fprintf(stderr, "<mark (timeout)>\n"); break; */ case DAT_SUCCESS: switch (event.event_number) { case DAT_CONNECTION_EVENT_TIMED_OUT: psdapl_dprint(2, "psdapl_accept_wait: event DAT_CONNECTION_EVENT_TIMED_OUT"); break; case DAT_CONNECTION_REQUEST_EVENT: psdapl_dprint(3, "psdapl_accept_wait: event DAT_CONNECTION_REQUEST_EVENT"); DAT_CR_ARRIVAL_EVENT_DATA *cr = &event.event_data.cr_arrival_event_data; DAT_CR_PARAM cr_param; dat_rc = dat_cr_query(cr->cr_handle, DAT_CR_FIELD_ALL, &cr_param); assert(dat_rc == DAT_SUCCESS); psdapl_init_msg_t *imsg = (psdapl_init_msg_t *)(cr_param.private_data); return _psdapl_get_con_accept(ci, cr->cr_handle, imsg); break; /* DAT_DTO_COMPLETION_EVENT = 0x00001, DAT_RMR_BIND_COMPLETION_EVENT = 0x01001, DAT_CONNECTION_REQUEST_EVENT = 0x02001, DAT_CONNECTION_EVENT_ESTABLISHED = 0x04001, DAT_CONNECTION_EVENT_PEER_REJECTED = 0x04002, DAT_CONNECTION_EVENT_NON_PEER_REJECTED = 0x04003, DAT_CONNECTION_EVENT_ACCEPT_COMPLETION_ERROR = 0x04004, DAT_CONNECTION_EVENT_DISCONNECTED = 0x04005, DAT_CONNECTION_EVENT_BROKEN = 0x04006, DAT_CONNECTION_EVENT_TIMED_OUT = 0x04007, DAT_CONNECTION_EVENT_UNREACHABLE = 0x04008, DAT_ASYNC_ERROR_EVD_OVERFLOW = 0x08001, DAT_ASYNC_ERROR_IA_CATASTROPHIC = 0x08002, DAT_ASYNC_ERROR_EP_BROKEN = 0x08003, DAT_ASYNC_ERROR_TIMED_OUT = 0x08004, DAT_ASYNC_ERROR_PROVIDER_INTERNAL_ERROR = 0x08005, DAT_SOFTWARE_EVENT = 0x10001 */ default: psdapl_dprint(2, "psdapl_accept_wait: unexpected event 0x%x", (unsigned)event.event_number); break; } break; default: psdapl_dprint_dat_err(1, dat_rc, "psdapl_accept_wait: dat_evd_wait()"); } return -1; }