LWMsgStatus lwmsg_assoc_acquire_call( LWMsgAssoc* assoc, LWMsgCall** call ) { LWMsgStatus status = LWMSG_STATUS_SUCCESS; LWMsgSession* session = NULL; if (assoc->call.in_use) { BAIL_ON_ERROR(status = LWMSG_STATUS_BUSY); } else { switch (lwmsg_assoc_get_state(assoc)) { case LWMSG_ASSOC_STATE_IDLE: break; case LWMSG_ASSOC_STATE_NOT_ESTABLISHED: BAIL_ON_ERROR(status = assoc->aclass->get_session(assoc, &session)); BAIL_ON_ERROR(status = lwmsg_assoc_connect(assoc, session)); break; default: BAIL_ON_ERROR(status = LWMSG_STATUS_INVALID_STATE); } assoc->call.in_use = LWMSG_TRUE; *call = LWMSG_CALL(&assoc->call); } error: return status; }
static LWMsgStatus lwmsg_peer_task_run_connect( LWMsgPeer* peer, PeerAssocTask* task, LWMsgTaskTrigger trigger, LWMsgTaskTrigger* next_trigger, LWMsgTime* next_timeout ) { LWMsgStatus status = LWMSG_STATUS_SUCCESS; status = lwmsg_assoc_connect(task->assoc, (LWMsgSession*) task->session); switch (status) { case LWMSG_STATUS_SUCCESS: task->type = PEER_TASK_DISPATCH; BAIL_ON_ERROR(status = lwmsg_peer_log_connect(task)); /* Set up the fd the assoc just created for events */ BAIL_ON_ERROR(status = lwmsg_task_set_trigger_fd(task->event_task, CONNECTION_PRIVATE(task->assoc)->fd)); break; case LWMSG_STATUS_PENDING: task->type = PEER_TASK_FINISH_CONNECT; /* Even if the connect pended, the fd is now available. Set it up for events */ BAIL_ON_ERROR(status = lwmsg_task_set_trigger_fd(task->event_task, CONNECTION_PRIVATE(task->assoc)->fd)); /* Restore status code */ status = LWMSG_STATUS_PENDING; lwmsg_peer_task_set_timeout(peer, task, &peer->timeout.establish, trigger, next_trigger, next_timeout); break; default: BAIL_ON_ERROR(status = lwmsg_peer_task_handle_assoc_error( peer, task, status)); break; } done: return status; error: goto done; }