/** * Respond to a sent message. * This will create a node representing the recipient for this process and free the node. */ void respond_to_message(Message* response, const char* recipient_name, Node* sender){ assert(sender->status == RECIEVED_MESSAGE); Node* recipient = create_node(recipient_name, sizeof(Message), READ | WRITE); assert(recipient->status == WAITING_FOR_RESPONSE); if (response){ transfer_message(response, recipient); } else{ strcpy(recipient->buffer, ""); } //recipient->status = HANDLING_RESPONSE; recipient->status = AVAILABLE; detatch_node(recipient); sender->status = AVAILABLE; }
/** * Send a message and receive a response. * This will create a node representing the recipient for this process and free the node. */ Message* send_message(Message* message, const char* recipient, Node* sender){ Node* recipient_node = create_node(recipient, sizeof(Message), READ | WRITE); // Copy bytes transfer_message(message, recipient_node); sender->status = WAITING_FOR_RESPONSE; // Wait for response recipient_node->status = RECIEVED_MESSAGE; detatch_node(recipient_node); //while (sender->status != HANDLING_RESPONSE){ while (sender->status != AVAILABLE){ sleep(1); } // Return the response //sender->status = AVAILABLE; return (Message*)(&(sender->buffer)); }
static WriterResult ParallelWriterClose(ParallelWriter *self, bool onError) { WriterResult ret = { 0 }; if (!self->base.rel) self->writer->close(self->writer, onError); /* wait for reader */ if (self->conn) { if (self->queue && !onError) { PGresult *res; int sock; fd_set input_mask; /* terminate with zero */ write_queue(self, NULL, 0); do { sock = PQsocket(self->conn); FD_ZERO(&input_mask); FD_SET(sock, &input_mask); while (select(sock + 1, &input_mask, NULL, NULL, NULL) < 0) { if (errno == EINTR) { CHECK_FOR_INTERRUPTS(); continue; } ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("select() failed"), errdetail("%s", finish_and_get_message(self)))); } PQconsumeInput(self->conn); } while (PQisBusy(self->conn)); res = PQgetResult(self->conn); if (PQresultStatus(res) != PGRES_TUPLES_OK) { PQfinish(self->conn); self->conn = NULL; transfer_message(NULL, res); } else { self->base.count = ParseInt64(PQgetvalue(res, 0, 1), 0); ret.num_dup_new = ParseInt64(PQgetvalue(res, 0, 3), 0); ret.num_dup_old = ParseInt64(PQgetvalue(res, 0, 4), 0); PQclear(res); /* commit transaction */ res = PQexec(self->conn, "COMMIT"); if (PQresultStatus(res) != PGRES_COMMAND_OK) { ereport(ERROR, (errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION), errmsg("could not commit transaction"), errdetail("%s", finish_and_get_message(self)))); } } PQclear(res); } else if (PQisBusy(self->conn)) { char errbuf[256]; PGcancel *cancel = PQgetCancel(self->conn); if (cancel) PQcancel(cancel, errbuf, lengthof(errbuf)); } if (self->conn) PQfinish(self->conn); self->conn = NULL; } /* * Close self after wait for reader because reader hasn't opened the self * yet. If we close self too early, the reader cannot open the self. */ if (self->queue) QueueClose(self->queue); self->queue = NULL; if (!onError) { MemoryContextDelete(self->base.context); if (self->base.rel) heap_close(self->base.rel, NoLock); } return ret; }