-/**
- * \brief Waits for communication completion
- * \param comm The communication
- * \param timeout The max amount of time to wait for the communication to finish
- *
- * Throws:
- * - host_error if local peer failed
- * - timeout_error if communication reached the timeout specified (either because of local peer or remote peer)
- * - network_error if network failed or remote peer failed
- */
-static XBT_INLINE void SIMIX_communication_wait_for_completion(smx_comm_t comm, double timeout)
-{
- smx_action_t act_sleep = NULL;
- int src_timeout = 0;
- int dst_timeout = 0;
-
- DEBUG1("Waiting for the completion of communication %p", comm);
-
- if (timeout >= 0) {
- act_sleep = SIMIX_action_sleep(SIMIX_host_self(), timeout);
- if(SIMIX_process_self()==comm->src_proc)
- comm->src_timeout = act_sleep;
- else
- comm->dst_timeout = act_sleep;
- SIMIX_action_set_name(act_sleep,bprintf("Timeout for comm %p and wait on semaphore %p (max_duration:%f)", comm, comm->sem,timeout));
- SIMIX_register_action_to_semaphore(act_sleep, comm->sem);
- SIMIX_process_self()->waiting_action = act_sleep;
- SIMIX_sem_block_onto(comm->sem);
- SIMIX_process_self()->waiting_action = NULL;
- SIMIX_unregister_action_to_semaphore(act_sleep, comm->sem);
- } else {
- SIMIX_sem_acquire(comm->sem);
+ /* If the action is still in a rendez-vous point then remove from it */
+ if (action->comm.rdv)
+ SIMIX_rdv_remove(action->comm.rdv, action);
+
+ DEBUG1("SIMIX_comm_finish: action state = %d", action->state);
+
+ /* Check out for errors */
+ switch (action->state) {
+
+ case SIMIX_DONE:
+ DEBUG1("Communication %p complete!", action);
+ SIMIX_comm_copy_data(action);
+ break;
+
+ case SIMIX_SRC_TIMEOUT:
+ TRY {
+ THROW0(timeout_error, 0, "Communication timeouted because of sender");
+ }
+ CATCH(req->issuer->running_ctx->exception) {
+ req->issuer->doexception = 1;
+ }
+ break;
+
+ case SIMIX_DST_TIMEOUT:
+ TRY {
+ THROW0(timeout_error, 0, "Communication timeouted because of receiver");
+ }
+ CATCH(req->issuer->running_ctx->exception) {
+ req->issuer->doexception = 1;
+ }
+ break;
+
+ case SIMIX_SRC_HOST_FAILURE:
+ TRY {
+ if (req->issuer == action->comm.src_proc)
+ THROW0(host_error, 0, "Host failed");
+ else
+ THROW0(network_error, 0, "Remote peer failed");
+ }
+ CATCH(req->issuer->running_ctx->exception) {
+ req->issuer->doexception = 1;
+ }
+ break;
+
+ case SIMIX_DST_HOST_FAILURE:
+ TRY {
+ if (req->issuer == action->comm.dst_proc)
+ THROW0(host_error, 0, "Host failed");
+ else
+ THROW0(network_error, 0, "Remote peer failed");
+ }
+ CATCH(req->issuer->running_ctx->exception) {
+ req->issuer->doexception = 1;
+ }
+ break;
+
+ case SIMIX_LINK_FAILURE:
+ TRY {
+ DEBUG5("Link failure in action %p between '%s' and '%s': posting an exception to the issuer: %s (%p)",
+ action, action->comm.src_proc->smx_host->name, action->comm.dst_proc->smx_host->name,
+ req->issuer->name, req->issuer);
+ THROW0(network_error, 0, "Link failure");
+ }
+ CATCH(req->issuer->running_ctx->exception) {
+ req->issuer->doexception = 1;
+ }
+ break;
+
+ default:
+ THROW_IMPOSSIBLE;
+ }
+ req->issuer->waiting_action = NULL;
+ SIMIX_request_answer(req);