Exemplo n.º 1
0
/* --------------------------------
 *		pq_recvbuf - load some bytes into the input buffer
 *
 *		returns 0 if OK, EOF if trouble
 * --------------------------------
 */
static int
pq_recvbuf(void)
{
    if (PqRecvPointer > 0)
    {
        if (PqRecvLength > PqRecvPointer)
        {
            /* still some unread data, left-justify it in the buffer */
            memmove(PqRecvBuffer, PqRecvBuffer + PqRecvPointer,
                    PqRecvLength - PqRecvPointer);
            PqRecvLength -= PqRecvPointer;
            PqRecvPointer = 0;
        }
        else
            PqRecvLength = PqRecvPointer = 0;
    }

    /* Ensure that we're in blocking mode */
    pq_set_nonblocking(false);

    /* Can fill buffer from PqRecvLength and upwards */
    for (;;)
    {
        int			r;

        r = secure_read(MyProcPort, PqRecvBuffer + PqRecvLength,
                        PQ_RECV_BUFFER_SIZE - PqRecvLength);

        if (r < 0)
        {
            if (errno == EINTR)
                continue;		/* Ok if interrupted */

            /*
             * Careful: an ereport() that tries to write to the client would
             * cause recursion to here, leading to stack overflow and core
             * dump!  This message must go *only* to the postmaster log.
             */
            ereport(COMMERROR,
                    (errcode_for_socket_access(),
                     errmsg("could not receive data from client: %m")));
            return EOF;
        }
        if (r == 0)
        {
            /*
             * EOF detected.  We used to write a log message here, but it's
             * better to expect the ultimate caller to do that.
             */
            return EOF;
        }
        /* r contains number of bytes read, so just incr length */
        PqRecvLength += r;
        return 0;
    }
}
Exemplo n.º 2
0
/* --------------------------------
 *		pq_flush		- flush pending output
 *
 *		returns 0 if OK, EOF if trouble
 * --------------------------------
 */
int
pq_flush(void)
{
    int			res;

    /* No-op if reentrant call */
    if (PqCommBusy)
        return 0;
    PqCommBusy = true;
    pq_set_nonblocking(false);
    res = internal_flush();
    PqCommBusy = false;
    return res;
}
Exemplo n.º 3
0
/* --------------------------------
 *		pq_getbyte_if_available - get a single byte from connection,
 *			if available
 *
 * The received byte is stored in *c. Returns 1 if a byte was read,
 * 0 if no data was available, or EOF if trouble.
 * --------------------------------
 */
int
pq_getbyte_if_available(unsigned char *c)
{
    int			r;

    if (PqRecvPointer < PqRecvLength)
    {
        *c = PqRecvBuffer[PqRecvPointer++];
        return 1;
    }

    /* Put the socket into non-blocking mode */
    pq_set_nonblocking(true);

    r = secure_read(MyProcPort, c, 1);
    if (r < 0)
    {
        /*
         * Ok if no data available without blocking or interrupted (though
         * EINTR really shouldn't happen with a non-blocking socket).
         * Report other errors.
         */
        if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
            r = 0;
        else
        {
            /*
             * Careful: an ereport() that tries to write to the client
             * would cause recursion to here, leading to stack overflow
             * and core dump!  This message must go *only* to the
             * postmaster log.
             */
            ereport(COMMERROR,
                    (errcode_for_socket_access(),
                     errmsg("could not receive data from client: %m")));
            r = EOF;
        }
    }
    else if (r == 0)
    {
        /* EOF detected */
        r = EOF;
    }

    return r;
}
Exemplo n.º 4
0
/* --------------------------------
 *		pq_flush		- flush pending output
 *
 *		returns 0 if OK, EOF if trouble
 * --------------------------------
 */
int
pq_flush(void)
{
	int			res;

	if ((Gp_role == GP_ROLE_DISPATCH || Gp_role == GP_ROLE_DISPATCHAGENT) && IsUnderPostmaster)
	{
		if (!pq_send_mutex_lock())
		{
			return EOF;
		}
	}
	pq_set_nonblocking(false);
	res = internal_flush();

	if ((Gp_role == GP_ROLE_DISPATCH || Gp_role == GP_ROLE_DISPATCHAGENT) && IsUnderPostmaster)
		pthread_mutex_unlock(&send_mutex);
	return res;
}
Exemplo n.º 5
0
/* --------------------------------
 *		pq_flush_if_writable - flush pending output if writable without blocking
 *
 * Returns 0 if OK, or EOF if trouble.
 * --------------------------------
 */
int
pq_flush_if_writable(void)
{
    int			res;

    /* Quick exit if nothing to do */
    if (PqSendPointer == PqSendStart)
        return 0;

    /* No-op if reentrant call */
    if (PqCommBusy)
        return 0;

    /* Temporarily put the socket into non-blocking mode */
    pq_set_nonblocking(true);

    PqCommBusy = true;
    res = internal_flush();
    PqCommBusy = false;
    return res;
}
Exemplo n.º 6
0
/* --------------------------------
 *		pq_flush_if_writable - flush pending output if writable without blocking
 *
 * Returns 0 if OK, or EOF if trouble.
 * --------------------------------
 */
int
pq_flush_if_writable(void)
{
	int			res;

	/* Quick exit if nothing to do */
	if (PqSendPointer == PqSendStart)
		return 0;
	if ((Gp_role == GP_ROLE_DISPATCH || Gp_role == GP_ROLE_DISPATCHAGENT) && IsUnderPostmaster)
	{
		if (!pq_send_mutex_lock())
		{
			return EOF;
		}
	}
	/* Temporarily put the socket into non-blocking mode */
	pq_set_nonblocking(true);

	res = internal_flush();
	if ((Gp_role == GP_ROLE_DISPATCH || Gp_role == GP_ROLE_DISPATCHAGENT) && IsUnderPostmaster)
		pthread_mutex_unlock(&send_mutex);
	return res;
}
Exemplo n.º 7
0
static int
internal_putbytes(const char *s, size_t len)
{
    size_t		amount;

    while (len > 0)
    {
        /* If buffer is full, then flush it out */
        if (PqSendPointer >= PqSendBufferSize)
        {
            pq_set_nonblocking(false);
            if (internal_flush())
                return EOF;
        }
        amount = PqSendBufferSize - PqSendPointer;
        if (amount > len)
            amount = len;
        memcpy(PqSendBuffer + PqSendPointer, s, amount);
        PqSendPointer += amount;
        s += amount;
        len -= amount;
    }
    return 0;
}