void send(const typed_actor<Rs...>& whom, Ts... what) { check_typed_input(whom, detail::type_list<typename detail::implicit_conversions< typename detail::rm_const_and_ref<Ts>::type >::type...>{}); send_tuple(message_priority::normal, actor{whom.m_ptr.get()}, make_message(std::forward<Ts>(what)...)); }
void local_actor::reply_message(any_tuple&& what) { auto& whom = m_current_node->sender; if (!whom) return; auto& id = m_current_node->mid; if (id.valid() == false || id.is_response()) { send_tuple(detail::raw_access::get(whom), std::move(what)); } else if (!id.is_answered()) { auto ptr = detail::raw_access::get(whom); ptr->enqueue({address(), ptr, id.response_id()}, std::move(what)); id.mark_as_answered(); } }
void local_actor::reply_message(message&& what) { auto& whom = m_current_node->sender; if (!whom) { return; } auto& id = m_current_node->mid; if (id.valid() == false || id.is_response()) { send_tuple(actor_cast<channel>(whom), std::move(what)); } else if (!id.is_answered()) { auto ptr = actor_cast<actor>(whom); ptr->enqueue(address(), id.response_id(), std::move(what), host()); id.mark_as_answered(); } }
inline void send(destination_header hdr, Ts&&... what) { static_assert(sizeof...(Ts) > 0, "no message to send"); send_tuple(std::move(hdr), make_any_tuple(std::forward<Ts>(what)...)); }
inline typename std::enable_if<std::is_base_of<channel, C>::value, const intrusive_ptr<C>& >::type operator<<(const intrusive_ptr<C>& whom, any_tuple what) { send_tuple(whom, std::move(what)); return whom; }
inline void send(const channel& whom, Ts&&... what) { static_assert(sizeof...(Ts) > 0, "sizeof...(Ts) == 0"); send_tuple(message_priority::normal, whom, make_message(std::forward<Ts>(what)...)); }
/** * Sends `what` to the receiver specified in `dest`. */ inline void send_tuple(const channel& whom, message what) { send_tuple(message_priority::normal, whom, std::move(what)); }
/** * Handle GETs and READs, both blocking and non-blocking. */ static void handle_get_read(struct context *ctx, struct tuple *s, int remove, int blocking) { struct ttuple *p; int clientnr = ctx - client_list; #if 0 GETLOG; LOGPRINTF("%s(%d) wants a tuple:", ctx->peername, ctx->id); LOGTUPLE(s); YIELDLOG; #endif while (1) { status_list[clientnr]='a'; GETACCESS; for (p = first_message; p != NULL; p = p->next) { if (tuples_match(p->tuple, s)) { if (remove) { remove_message_from_space(p); } YIELDACCESS; GETLOG; LOGPRINTF("%s(%d) %s a tuple:", ctx->peername, ctx->id, (remove)?"gets":"reads"); LOGTUPLE(p->tuple); YIELDLOG; if (send_tuple(ctx, p->tuple)) { PRINTF("send_tuple failed\n"); /* Assume the client died while blocked. * If the tuple was removed, put it back. * Otherwise just kill this thread. */ LOGPRINTF("send_tuple failed\n"); LOGTUPLE(s); DBGPRINTF("remove=%d\n", remove); if (remove) { add_tuple_to_space(p->tuple); destroy_tuple(s); return; } } if (remove) { destroy_tuple(p->tuple); } destroy_tuple(s); return; } } #if 0 GETLOG; LOGPRINTF("Socket %d couldn't find a match for ", ctx->sock); LOGTUPLE(s); YIELDLOG; #endif YIELDACCESS; if (blocking) { /* wait for a tuple that might match */ #ifdef USE_SEMA num_blocked++; if (sem_wait(&blocked_sem)) perror("sem_wait"); #else status_list[clientnr]='m'; if (pthread_mutex_lock(&blocked_mutex)) perror("mutex_lock"); status_list[clientnr]='b'; if (pthread_cond_wait(&blocked_cond, &blocked_mutex)) perror("cond_wait"); status_list[clientnr]='u'; if (pthread_mutex_unlock(&blocked_mutex)) perror("mutex_unlock"); #endif } else { /* don't wait, return a failure code */ int ack = -1; if (send_chunk(ctx, (char *) &ack, sizeof(int))) { perror("Cannot send -1 return code"); } return; } } }
inline void send(channel_destination dest, Ts&&... what) { static_assert(sizeof...(Ts) > 0, "no message to send"); send_tuple(std::move(dest), make_any_tuple(std::forward<Ts>(what)...)); }