mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 15:11:34 +00:00 
			
		
		
		
	svn+ssh://pythondev@svn.python.org/python/trunk ........ r81029 | antoine.pitrou | 2010-05-09 16:46:46 +0200 (dim., 09 mai 2010) | 3 lines Untabify C files. Will watch buildbots. ........
		
			
				
	
	
		
			149 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			149 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * A type which wraps a pipe handle in message oriented mode
 | 
						|
 *
 | 
						|
 * pipe_connection.c
 | 
						|
 *
 | 
						|
 * Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
 | 
						|
 */
 | 
						|
 | 
						|
#include "multiprocessing.h"
 | 
						|
 | 
						|
#define CLOSE(h) CloseHandle(h)
 | 
						|
 | 
						|
/*
 | 
						|
 * Send string to the pipe; assumes in message oriented mode
 | 
						|
 */
 | 
						|
 | 
						|
static Py_ssize_t
 | 
						|
conn_send_string(ConnectionObject *conn, char *string, size_t length)
 | 
						|
{
 | 
						|
    DWORD amount_written;
 | 
						|
    BOOL ret;
 | 
						|
 | 
						|
    Py_BEGIN_ALLOW_THREADS
 | 
						|
    ret = WriteFile(conn->handle, string, length, &amount_written, NULL);
 | 
						|
    Py_END_ALLOW_THREADS
 | 
						|
 | 
						|
    if (ret == 0 && GetLastError() == ERROR_NO_SYSTEM_RESOURCES) {
 | 
						|
        PyErr_Format(PyExc_ValueError, "Cannnot send %" PY_FORMAT_SIZE_T "d bytes over connection", length);
 | 
						|
        return MP_STANDARD_ERROR;
 | 
						|
    }
 | 
						|
 | 
						|
    return ret ? MP_SUCCESS : MP_STANDARD_ERROR;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Attempts to read into buffer, or if buffer too small into *newbuffer.
 | 
						|
 *
 | 
						|
 * Returns number of bytes read.  Assumes in message oriented mode.
 | 
						|
 */
 | 
						|
 | 
						|
static Py_ssize_t
 | 
						|
conn_recv_string(ConnectionObject *conn, char *buffer,
 | 
						|
                 size_t buflength, char **newbuffer, size_t maxlength)
 | 
						|
{
 | 
						|
    DWORD left, length, full_length, err;
 | 
						|
    BOOL ret;
 | 
						|
    *newbuffer = NULL;
 | 
						|
 | 
						|
    Py_BEGIN_ALLOW_THREADS
 | 
						|
    ret = ReadFile(conn->handle, buffer, MIN(buflength, maxlength),
 | 
						|
                  &length, NULL);
 | 
						|
    Py_END_ALLOW_THREADS
 | 
						|
    if (ret)
 | 
						|
        return length;
 | 
						|
 | 
						|
    err = GetLastError();
 | 
						|
    if (err != ERROR_MORE_DATA) {
 | 
						|
        if (err == ERROR_BROKEN_PIPE)
 | 
						|
            return MP_END_OF_FILE;
 | 
						|
        return MP_STANDARD_ERROR;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!PeekNamedPipe(conn->handle, NULL, 0, NULL, NULL, &left))
 | 
						|
        return MP_STANDARD_ERROR;
 | 
						|
 | 
						|
    full_length = length + left;
 | 
						|
    if (full_length > maxlength)
 | 
						|
        return MP_BAD_MESSAGE_LENGTH;
 | 
						|
 | 
						|
    *newbuffer = PyMem_Malloc(full_length);
 | 
						|
    if (*newbuffer == NULL)
 | 
						|
        return MP_MEMORY_ERROR;
 | 
						|
 | 
						|
    memcpy(*newbuffer, buffer, length);
 | 
						|
 | 
						|
    Py_BEGIN_ALLOW_THREADS
 | 
						|
    ret = ReadFile(conn->handle, *newbuffer+length, left, &length, NULL);
 | 
						|
    Py_END_ALLOW_THREADS
 | 
						|
    if (ret) {
 | 
						|
        assert(length == left);
 | 
						|
        return full_length;
 | 
						|
    } else {
 | 
						|
        PyMem_Free(*newbuffer);
 | 
						|
        return MP_STANDARD_ERROR;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Check whether any data is available for reading
 | 
						|
 */
 | 
						|
 | 
						|
static int
 | 
						|
conn_poll(ConnectionObject *conn, double timeout, PyThreadState *_save)
 | 
						|
{
 | 
						|
    DWORD bytes, deadline, delay;
 | 
						|
    int difference, res;
 | 
						|
    BOOL block = FALSE;
 | 
						|
 | 
						|
    if (!PeekNamedPipe(conn->handle, NULL, 0, NULL, &bytes, NULL))
 | 
						|
        return MP_STANDARD_ERROR;
 | 
						|
 | 
						|
    if (timeout == 0.0)
 | 
						|
        return bytes > 0;
 | 
						|
 | 
						|
    if (timeout < 0.0)
 | 
						|
        block = TRUE;
 | 
						|
    else
 | 
						|
        /* XXX does not check for overflow */
 | 
						|
        deadline = GetTickCount() + (DWORD)(1000 * timeout + 0.5);
 | 
						|
 | 
						|
    Sleep(0);
 | 
						|
 | 
						|
    for (delay = 1 ; ; delay += 1) {
 | 
						|
        if (!PeekNamedPipe(conn->handle, NULL, 0, NULL, &bytes, NULL))
 | 
						|
            return MP_STANDARD_ERROR;
 | 
						|
        else if (bytes > 0)
 | 
						|
            return TRUE;
 | 
						|
 | 
						|
        if (!block) {
 | 
						|
            difference = deadline - GetTickCount();
 | 
						|
            if (difference < 0)
 | 
						|
                return FALSE;
 | 
						|
            if ((int)delay > difference)
 | 
						|
                delay = difference;
 | 
						|
        }
 | 
						|
 | 
						|
        if (delay > 20)
 | 
						|
            delay = 20;
 | 
						|
 | 
						|
        Sleep(delay);
 | 
						|
 | 
						|
        /* check for signals */
 | 
						|
        Py_BLOCK_THREADS
 | 
						|
        res = PyErr_CheckSignals();
 | 
						|
        Py_UNBLOCK_THREADS
 | 
						|
 | 
						|
        if (res)
 | 
						|
            return MP_EXCEPTION_HAS_BEEN_SET;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * "connection.h" defines the PipeConnection type using the definitions above
 | 
						|
 */
 | 
						|
 | 
						|
#define CONNECTION_NAME "PipeConnection"
 | 
						|
#define CONNECTION_TYPE PipeConnectionType
 | 
						|
 | 
						|
#include "connection.h"
 |