Пример #1
0
/**
 * 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;
}
Пример #2
0
/**
 * 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));
}
Пример #3
0
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;
}