+
+int
+MSG_task_listen_from(const char* alias)
+{
+ m_task_t task;
+
+ CHECK_HOST();
+
+ if(NULL == (task = MSG_mailbox_get_head(MSG_mailbox_get_by_alias(alias))))
+ return -1;
+
+ return MSG_process_get_PID(task->simdata->sender);
+}
+
+/** \ingroup msg_gos_functions
+ * \brief Wait for at most \a max_duration second for a task reception
+ on \a channel.
+
+ * \a PID is updated with the PID of the first process that triggered this event if any.
+ *
+ * It takes three parameters:
+ * \param channel the channel on which the agent should be
+ listening. This value has to be >=0 and < than the maximal.
+ number of channels fixed with MSG_set_channel_number().
+ * \param PID a memory location for storing an int.
+ * \param timeout the maximum time to wait for a task before
+ giving up. In the case of a reception, *\a PID will be updated
+ with the PID of the first process to send a task.
+ * \return #MSG_HOST_FAILURE if the host is shut down in the meantime
+ and #MSG_OK otherwise.
+ */
+MSG_error_t
+MSG_channel_select_from(m_channel_t channel,double timeout, int *PID)
+{
+ m_host_t h = NULL;
+ simdata_host_t h_simdata = NULL;
+ m_task_t t;
+ int first_time = 1;
+ smx_cond_t cond;
+ msg_mailbox_t mailbox;
+
+ xbt_assert1((channel >= 0) && (channel < msg_global->max_channel), "Invalid channel %d",channel);
+
+ if(PID)
+ {
+ *PID = -1;
+ }
+
+ if (timeout == 0.0)
+ {
+ *PID = MSG_task_probe_from(channel);
+ MSG_RETURN(MSG_OK);
+ }
+ else
+ {
+ CHECK_HOST();
+ h = MSG_host_self();
+ h_simdata = h->simdata;
+
+ mailbox = MSG_mailbox_get_by_channel(MSG_host_self(), channel);
+
+ while(MSG_mailbox_is_empty(mailbox))
+ {
+ if(timeout > 0)
+ {
+ if (!first_time)
+ {
+ MSG_RETURN(MSG_OK);
+ }
+ }
+
+ SIMIX_mutex_lock(h_simdata->mutex);
+
+ xbt_assert1(!MSG_mailbox_get_cond(mailbox),"A process is already blocked on this channel %d",channel);
+
+ cond = SIMIX_cond_init();
+
+ MSG_mailbox_set_cond(mailbox, cond);
+
+ if (timeout > 0)
+ {
+ SIMIX_cond_wait_timeout(cond, h_simdata->mutex, timeout);
+ }
+ else
+ {
+ SIMIX_cond_wait(cond, h_simdata->mutex);
+ }
+
+ SIMIX_cond_destroy(cond);
+ SIMIX_mutex_unlock(h_simdata->mutex);
+
+ if (SIMIX_host_get_state(h_simdata->smx_host) == 0)
+ {
+ MSG_RETURN(MSG_HOST_FAILURE);
+ }
+
+ MSG_mailbox_set_cond(mailbox,NULL);
+ first_time = 0;
+ }
+
+ if(NULL == (t = MSG_mailbox_get_head(mailbox)))
+ MSG_RETURN(MSG_OK);
+
+
+ if (PID)
+ {
+ *PID = MSG_process_get_PID(t->simdata->sender);
+ }
+
+ MSG_RETURN(MSG_OK);
+ }
+}
+
+
+MSG_error_t
+MSG_alias_select_from(const char* alias, double timeout, int* PID)
+{
+ m_host_t h = NULL;
+ simdata_host_t h_simdata = NULL;
+ m_task_t t;
+ int first_time = 1;
+ smx_cond_t cond;
+ msg_mailbox_t mailbox;
+
+ if (PID)
+ {
+ *PID = -1;
+ }
+
+ if(timeout == 0.0)
+ {
+ *PID = MSG_task_listen_from(alias);
+ MSG_RETURN(MSG_OK);
+ }
+ else
+ {
+ CHECK_HOST();
+ h = MSG_host_self();
+ h_simdata = h->simdata;
+
+ DEBUG2("Probing on alias %s (%s)", alias, h->name);
+
+ mailbox = MSG_mailbox_get_by_alias(alias);
+
+ while(MSG_mailbox_is_empty(mailbox))
+ {
+ if(timeout > 0)
+ {
+ if (!first_time)
+ {
+ MSG_RETURN(MSG_OK);
+ }
+ }
+
+ SIMIX_mutex_lock(h_simdata->mutex);
+
+ xbt_assert1(!MSG_mailbox_get_cond(mailbox),"A process is already blocked on this alias %s",alias);
+
+ cond = SIMIX_cond_init();
+
+ MSG_mailbox_set_cond(mailbox, cond);
+
+ if (timeout > 0)
+ {
+ SIMIX_cond_wait_timeout(cond, h_simdata->mutex, timeout);
+ }
+ else
+ {
+ SIMIX_cond_wait(cond, h_simdata->mutex);
+ }
+
+ SIMIX_cond_destroy(cond);
+ SIMIX_mutex_unlock(h_simdata->mutex);
+
+ if (SIMIX_host_get_state(h_simdata->smx_host) == 0)
+ {
+ MSG_RETURN(MSG_HOST_FAILURE);
+ }
+
+ MSG_mailbox_set_cond(mailbox,NULL);
+ first_time = 0;
+ }
+
+ if(NULL == (t = MSG_mailbox_get_head(mailbox)))
+ MSG_RETURN(MSG_OK);
+
+
+ if (PID)
+ {
+ *PID = MSG_process_get_PID(t->simdata->sender);
+ }
+
+ MSG_RETURN(MSG_OK);
+ }
+}
+
+
+
+
+