int clj_read_error(char *str, const clj_Reader *r, clj_Result result) { return sprintf(str, "%s at line %d, column %d", result_message(result), r->line, r->column); }
gboolean button_press_event_handler(GtkWidget *widget, GdkEventButton *event, gpointer data) { cairo_t *pointCr = gdk_cairo_create(widget->window), *lineCr = gdk_cairo_create(widget->window), *player1BoxCr = gdk_cairo_create(widget->window), *player2BoxCr = gdk_cairo_create(widget->window); cairo_set_source_rgba_from_string(pointCr, POINT_COLOR, 1); cairo_set_source_rgba_from_string(lineCr, LINE_COLOR, 1); cairo_set_source_rgba_from_string(player1BoxCr, PLAYER_1_BOX_COLOR, 1); cairo_set_source_rgba_from_string(player2BoxCr, PLAYER_2_BOX_COLOR, 1); cairo_set_line_width(lineCr, pointRadius * 1.4); gint x = (gint) event->x, y = (gint) event->y; if (isClickInsideFrame(x, y)) { timer = true; fadingLineAlpha = -1; gtk_widget_queue_draw(event_box); timer = false; fadingLineAlpha = 1; buttonPressCount %= 2; TurnResult result; if (!buttonPressCount) { result = playerTurn(lineCr, player1BoxCr, pointCr, head, x, y, lineLength, pointRadius, &BoxOfPlayer1, firstPlayerBox); if (result == lineDrawn) { gtk_statusbar_pop(GTK_STATUSBAR(data), status_context_id); if (opponent == HUMAN) buttonPressCount++; else { g_signal_handler_block(event_box, button_press_handler_id); computerPoints = computerTurn(head, lineCr, player2BoxCr, pointCr, lineLength, pointRadius, &BoxOfPlayer2, secondPlayerBox, &event_box, difficulty); g_signal_handler_unblock(event_box, button_press_handler_id); if (!computerPoints) { gtk_statusbar_push(GTK_STATUSBAR(data), status_context_id, "Game Over"); timer = false; result_message(player1Name, player2Name, BoxOfPlayer1, BoxOfPlayer2); } else { gtk_statusbar_push(GTK_STATUSBAR(data), status_context_id, player1Name); if ((*computerPoints)->x == (*(computerPoints + 1))->x) (*computerPoints)->verticalDown = (*(computerPoints + 1))->verticalUp = true; else (*computerPoints)->horizontalRight = (*(computerPoints + 1))->horizontalLeft = true; timer = true; g_timeout_add(fadeTimeInterval, (GSourceFunc) fade_out_handler, NULL); } } } if (result == frameIsFull) { gtk_statusbar_push(GTK_STATUSBAR(data), status_context_id, "Game Over"); result_message(player1Name, player2Name, BoxOfPlayer1, BoxOfPlayer2); } } else { result = playerTurn(lineCr, player2BoxCr, pointCr, head, x, y, lineLength, pointRadius, &BoxOfPlayer2, secondPlayerBox); if (result == lineDrawn) { buttonPressCount++; gtk_statusbar_push(GTK_STATUSBAR(data), status_context_id, player1Name); } if (result == frameIsFull) { gtk_statusbar_push(GTK_STATUSBAR(data), status_context_id, "Game Over"); result_message(player1Name, player2Name, BoxOfPlayer1, BoxOfPlayer2); } } } cairo_destroy(pointCr); cairo_destroy(lineCr); cairo_destroy(player1BoxCr); cairo_destroy(player2BoxCr); return TRUE; }
void wamp_dealer::process_yield_message(const wamp_session_id& session_id, wamp_yield_message* yield_message) { auto session_itr = m_sessions.find(session_id); if (session_itr == m_sessions.end()) { throw std::logic_error("dealer session does not exist"); } // It is considered to be a normal condition if we cannot find the // associated invocation. Typically this occurs if the invocation // timed out or if the callers session has ended. BONEFISH_TRACE("%1%, %2%", *session_itr->second % *yield_message); const auto request_id = yield_message->get_request_id(); auto pending_invocations_itr = m_pending_invocations.find(request_id); if (pending_invocations_itr == m_pending_invocations.end()) { BONEFISH_TRACE("unable to find invocation ... timed out or session closed"); return; } const auto& dealer_invocation = pending_invocations_itr->second; std::shared_ptr<wamp_session> session = dealer_invocation->get_session(); // We can't have a pending invocation without a pending caller/callee // as they are tracked in a synchronized manner. So to have one without // the other is considered to be an error. auto pending_callee_invocations_itr = m_pending_callee_invocations.find(session_itr->second->get_session_id()); if (pending_callee_invocations_itr == m_pending_callee_invocations.end()) { throw std::logic_error("dealer pending callee invocations out of sync"); } pending_callee_invocations_itr->second.erase(request_id); auto pending_caller_invocations_itr = m_pending_caller_invocations.find(session->get_session_id()); if (pending_caller_invocations_itr == m_pending_caller_invocations.end()) { throw std::logic_error("dealer pending caller invocations out of sync"); } pending_caller_invocations_itr->second.erase(request_id); std::unique_ptr<wamp_result_message> result_message( new wamp_result_message(std::move(yield_message->release_zone()))); result_message->set_request_id(dealer_invocation->get_request_id()); result_message->set_arguments(yield_message->get_arguments()); result_message->set_arguments_kw(yield_message->get_arguments_kw()); // If we fail to send the result message it is most likely that the // underlying network connection has been closed/lost which means // that the caller is no longer reachable on this session. So all // we do here is trace the fact that this event occured. BONEFISH_TRACE("%1%, %2%", *session_itr->second % *result_message); if (!session->get_transport()->send_message(std::move(*result_message))) { BONEFISH_TRACE("failed to send result message to caller: network failure"); } // The failure to send a message in the event of a network failure // will detach the session. When this happens the pending invocations // be cleaned up. So we don't use an iterator here to erase the pending // invocation because it may have just been invalidated above. m_pending_callee_invocations[session_id].erase(request_id); m_pending_caller_invocations[session->get_session_id()].erase(request_id); m_pending_invocations.erase(request_id); }
void wamp_dealer::process_yield_message(const wamp_session_id& session_id, wamp_yield_message* yield_message) { auto session_itr = m_sessions.find(session_id); if (session_itr == m_sessions.end()) { throw std::logic_error("dealer session does not exist"); } // It is considered to be a normal condition if we cannot find the // associated invocation. Typically this occurs if the invocation // timed out or if the callers session has ended. BONEFISH_TRACE("%1%, %2%", *session_itr->second % *yield_message); const auto request_id = yield_message->get_request_id(); auto pending_invocations_itr = m_pending_invocations.find(request_id); if (pending_invocations_itr == m_pending_invocations.end()) { BONEFISH_TRACE("unable to find invocation ... timed out or session closed"); return; } const auto& dealer_invocation = pending_invocations_itr->second; std::shared_ptr<wamp_session> session = dealer_invocation->get_session(); // We can't have a pending invocation without a pending caller/callee // as they are tracked in a synchronized manner. So to have one without // the other is considered to be an error. assert(m_pending_callee_invocations.count(session_itr->second->get_session_id())); assert(m_pending_caller_invocations.count(session->get_session_id())); wamp_yield_options yield_options; yield_options.unmarshal(yield_message->get_options()); // You can't rely on simply assigning the yield options to the result // details. Some yield options may only be applicable to the dealer. // Likewise, some result details may be in addition to whatever is // provided in the yield options. As a result, we only copy specific // options over to the result details. wamp_result_details result_details; if (yield_options.get_option_or("progress", false)) { result_details.set_detail("progress", true); } std::unique_ptr<wamp_result_message> result_message( new wamp_result_message(yield_message->release_zone())); result_message->set_request_id(dealer_invocation->get_request_id()); result_message->set_details(result_details.marshal(result_message->get_zone())); result_message->set_arguments(yield_message->get_arguments()); result_message->set_arguments_kw(yield_message->get_arguments_kw()); // If we fail to send the result message it is most likely that the // underlying network connection has been closed/lost which means // that the caller is no longer reachable on this session. So all // we do here is trace the fact that this event occured. BONEFISH_TRACE("%1%, %2%", *session_itr->second % *result_message); if (!session->get_transport()->send_message(std::move(*result_message))) { BONEFISH_TRACE("failed to send result message to caller: network failure"); } // If the call has more results in progress then do not cleanup any of the // invocation state and just bail out here. if (yield_options.get_option_or("progress", false)) { return; } // Otherwise, the call still has results in progress so do not remove the // invocation. The failure to send a message in the event of a network failure // will detach the session. When this happens the pending invocations // be cleaned up. So we don't use an iterator here to erase the pending // invocation because it may have just been invalidated above if an // error occured. m_pending_callee_invocations[session_id].erase(request_id); m_pending_caller_invocations[session->get_session_id()].erase(request_id); m_pending_invocations.erase(request_id); }
void HandleMaps::issue_command_() { bool assigned = false; //Describes status of current chunk (file) while(assigned == false) { try { saga::stream::stream worker = service_->serve(); std::string message("Established connection to "); message += worker.get_url().get_string(); log_->write(message, MR_LOGLEVEL_INFO); // Ask worker for state. worker.write(saga::buffer(MASTER_QUESTION_STATE, 6)); if (!SagaStreamUtils::TimedWaitForRead( worker, job_.get_attribute("protocol.read_timeout", 10))) { log_->write("Worker didn't respond -- retrying.", MR_LOGLEVEL_DEBUG); delete service_; service_ = new saga::stream::server(serverURL_); continue; } char buff[MSG_BUFFER_SIZE]; saga::ssize_t read_bytes = worker.read(saga::buffer(buff)); std::string state(buff, read_bytes); message.clear(); message = "Worker: " + worker.get_url().get_string() + " has state " + state; log_->write(message, MR_LOGLEVEL_INFO); if(state == WORKER_STATE_IDLE) { if(finished_.size() == totalChunks_ || unassigned_.size() == 0) { //Prevent unneccessary work assignments worker.write(saga::buffer(MASTER_REQUEST_IDLE, 5)); saga::ssize_t read_bytes = worker.read(saga::buffer(buff)); if(std::string(buff, read_bytes) != WORKER_RESPONSE_ACKNOWLEDGE) { log_->write(std::string("Misbehaving worker!"), MR_LOGLEVEL_WARNING); } return; } std::string chunk_id(getCandidate_(worker)); //Worker is idle message.clear(); message = "Attempting to issue worker "; message += worker.get_url().get_string(); message += " to map " + chunk_id; message += " ..."; log_->write(message, MR_LOGLEVEL_INFO); //ask where their advert is worker.write(saga::buffer(MASTER_QUESTION_ADVERT, 7)); memset(buff, 0, MSG_BUFFER_SIZE); read_bytes = worker.read(saga::buffer(buff)); saga::url advert = saga::url(std::string(buff, read_bytes)); // Store URL->advert mapping. worker_adverts_[worker.get_url().get_string()] = advert; message.clear(); message += worker.get_url().get_string(); message += " <==> " + std::string(buff); message += " ... "; log_->write(message, MR_LOGLEVEL_INFO); //Tell worker about data worker.write(saga::buffer(WORKER_COMMAND_MAP, 3)); memset(buff, 0, MSG_BUFFER_SIZE); read_bytes = worker.read(saga::buffer(buff)); if(std::string(buff, read_bytes) == WORKER_RESPONSE_ACKNOWLEDGE) { worker.write(saga::buffer(WORKER_CHUNK, 5)); memset(buff, 0, MSG_BUFFER_SIZE); read_bytes = worker.read(saga::buffer(buff)); if(std::string(buff, read_bytes) == WORKER_RESPONSE_ACKNOWLEDGE) { // Get chunk pointer for ID. InputChunk* chunk = chunk_assignments_[chunk_id]; // Give serialized JobDescription, chunk_id and chunk to worker. // FIXME: shouldn't we store chunk ID with the chunk/jobdesc? std::string command; { StringOutputStream sos(&command); SerializationHandler<JobDescription>::Serialize( const_cast<JobDescription*>(&job_), &sos); SerializationHandler<std::string>::Serialize(&chunk_id, &sos); input_format_->SerializeInputChunk(chunk, &sos); } worker.write(saga::buffer(command, command.size())); memset(buff, 0, MSG_BUFFER_SIZE); read_bytes = worker.read(saga::buffer(buff)); if (std::string(buff, read_bytes) == WORKER_RESPONSE_ACKNOWLEDGE) { // Add to assigned set. assigned_.insert(chunk_id); //Remove from unassigned. unassigned_.erase(chunk_id); } } } else { message = std::string("Worker did not accept chunk!"); log_->write(message, MR_LOGLEVEL_WARNING); break; } message.clear(); message += "Success: "; message += advert.get_string() + " is comparing chunk "; message += chunk_id; log_->write(message, MR_LOGLEVEL_INFO); assigned = true; } else if(state == WORKER_STATE_DONE_MAP) { worker.write(saga::buffer(MASTER_QUESTION_RESULT, 7)); memset(buff, 0, MSG_BUFFER_SIZE); read_bytes = worker.read(saga::buffer(buff)); std::string result_message(buff, read_bytes); worker.write(saga::buffer(MASTER_REQUEST_IDLE, 5)); // Parse result message. size_t split_point = result_message.find_first_of(' '); std::string chunk_id = result_message.substr(0, split_point); std::string worker_advert = result_message.substr(split_point+1); message.clear(); message += "Worker "; message += worker.get_url().get_string() + " finished chunk "; message += chunk_id; log_->write(message, MR_LOGLEVEL_INFO); // Note which worker completed this chunk. message.clear(); message += "Noted " + worker_advert + " for " + chunk_id; committed_chunks_[chunk_id] = worker_advert; // If in assigned, remove it. assigned_.erase(chunk_id); // Put into finished set. finished_.insert(chunk_id); } } catch(saga::exception const & e) { std::string message(e.what()); log_->write(message, MR_LOGLEVEL_ERROR); } } }