int changeState(cwpi_Scope s, const char *new_state) { MachineInstance *scope = static_cast<MachineInstance*>(s); if (!scope) { MessageLog::instance()->add("changeState was passed a null instance from a plugin"); return 0; } SetStateActionTemplate ssat("SELF", new_state ); if (scope->isActive()) scope->enqueueAction(ssat.factory(scope)); // execute this state change once all other actions are complete else scope->setState(new_state); return 1; }
Action::Status SyncRemoteStatesAction::execute() { Channel *chn = dynamic_cast<Channel*>(owner); if (internals->process_state == SyncRemoteStatesActionInternals::ps_init) { owner->start(this); status = Running; #if 0 if (!internals->sock){ internals->sock = new zmq::socket_t(*MessagingInterface::getContext(), ZMQ_PAIR); internals->sock->bind("inproc://syncstates"); chn->addSocket(10, "inproc://syncstates"); } #endif //assert(chn); //assert(chn == internals->chn); internals->process_state = SyncRemoteStatesActionInternals::ps_sending_messages; if (chn->syncRemoteStates(internals->messages)) { internals->iter = new std::list<char*>::iterator(internals->messages.begin()); if (*internals->iter != internals->messages.end()) internals->message_state = SyncRemoteStatesActionInternals::e_sending; else internals->message_state = SyncRemoteStatesActionInternals::e_done; } else{ status = Failed; error_str = "Failed to sync"; owner->stop(this); return status; } } if (internals->process_state == SyncRemoteStatesActionInternals::ps_sending_messages) { if (*internals->iter == internals->messages.end()) { internals->message_state = SyncRemoteStatesActionInternals::e_done; } if (internals->message_state == SyncRemoteStatesActionInternals::e_sending) { char *current_message = *(*internals->iter); internals->header.needReply(false); safeSend(*internals->sock, current_message, strlen(current_message), internals->header); free( current_message ); *internals->iter = internals->messages.erase(*internals->iter); internals->message_state = SyncRemoteStatesActionInternals::e_receiving; // skip receiving temporarily internals->message_state = SyncRemoteStatesActionInternals::e_done; } else if (internals->message_state == SyncRemoteStatesActionInternals::e_receiving) { char *buf; size_t len; if (safeRecv(*internals->sock, &buf, &len, false, 0, internals->header)) { //NB_MSG << "got reply: " << buf << "\n"; internals->message_state = SyncRemoteStatesActionInternals::e_done; delete[] buf; } else return Running; } if (internals->message_state == SyncRemoteStatesActionInternals::e_done) { if (*internals->iter != internals->messages.end()) { internals->message_state = SyncRemoteStatesActionInternals::e_sending; } else { if (internals->iter) {delete internals->iter; internals->iter =0; } } if (!internals->iter) { // finished sending messages if (internals->process_state == SyncRemoteStatesActionInternals::ps_sending_messages) { //safeSend(*cmd_client, "done", 4); std::string ack; //MessageHeader mh(ChannelInternals::SOCK_CTRL, ChannelInternals::SOCK_CTRL, false); //sendMessage("done", *cmd_client, ack, mh); internals->header.dest = MessageHeader::SOCK_CTRL; internals->header.dest = MessageHeader::SOCK_CTRL; internals->header.needReply(true); safeSend(*internals->sock, "done", 4, internals->header); internals->process_state = SyncRemoteStatesActionInternals::ps_waiting_ack; } } } } else if (internals->process_state == SyncRemoteStatesActionInternals::ps_waiting_ack) { char *ack; size_t len; if (safeRecv(*internals->sock, &ack, &len, false, 0, internals->header)) { DBG_CHANNELS << "channel " << chn->name << " got " << ack << " from server\n"; status = Complete; result_str = (const char *)ack; // force a new allocation delete[] ack; owner->stop(this); // execute a state change once all other actions are if (chn->isClient()) { SetStateActionTemplate ssat(CStringHolder("SELF"), "ACTIVE" ); SetStateAction *ssa = (SetStateAction*)ssat.factory(chn); chn->enqueueAction(ssa); } else { SetStateActionTemplate ssat(CStringHolder("SELF"), "DOWNLOADING" ); chn->enqueueAction(ssat.factory(chn)); } return status; } } return status; #if 0 std::stringstream ss; ss << owner->getName() << " failed to find machine " << target.get() << " for SetState action" << std::flush; std::string str = ss.str(); error_str = strdup(str.c_str()); status = Failed; owner->stop(this); return status; #endif }