- CATCH(e){
- /* If there is a timeout then cancel the communication if it is running or
- remove it from the rendez-vous otherwise. Then signal the other peer,
- destroy the communication and retrow the exception. */
- if(e.category == timeout_error){
- DEBUG1("Communication timeout! %p", comm);
- if(comm->act && SIMIX_action_get_state(comm->act) == SURF_ACTION_RUNNING)
- SIMIX_communication_cancel(comm);
- else
- SIMIX_rdv_remove(comm->rdv, comm);
-
- /* Make sure that everyone sleeping on that semaphore is awake, and that nobody will ever block on it */
- SIMIX_sem_release_forever(comm->sem);
- SIMIX_communication_destroy(comm);
- }
- RETHROW;
+
+ /* 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;