コード例 #1
0
ファイル: ossaudiodev.c プロジェクト: 1564143452/kbengine
static PyObject *
oss_writeall(oss_audio_t *self, PyObject *args)
{
    char *cp;
    int rv, size;
    fd_set write_set_fds;
    int select_rv;

    /* NB. writeall() is only useful in non-blocking mode: according to
       Guenter Geiger <*****@*****.**> on the linux-audio-dev list
       (http://eca.cx/lad/2002/11/0380.html), OSS guarantees that
       write() in blocking mode consumes the whole buffer.  In blocking
       mode, the behaviour of write() and writeall() from Python is
       indistinguishable. */

    if (!_is_fd_valid(self->fd))
        return NULL;

    if (!PyArg_ParseTuple(args, "y#:write", &cp, &size))
        return NULL;

    if (!_PyIsSelectable_fd(self->fd)) {
        PyErr_SetString(PyExc_ValueError,
                        "file descriptor out of range for select");
        return NULL;
    }
    /* use select to wait for audio device to be available */
    FD_ZERO(&write_set_fds);
    FD_SET(self->fd, &write_set_fds);

    while (size > 0) {
        Py_BEGIN_ALLOW_THREADS
        select_rv = select(self->fd+1, NULL, &write_set_fds, NULL, NULL);
        Py_END_ALLOW_THREADS
        assert(select_rv != 0);         /* no timeout, can't expire */
        if (select_rv == -1)
            return PyErr_SetFromErrno(PyExc_IOError);

        Py_BEGIN_ALLOW_THREADS
        rv = write(self->fd, cp, size);
        Py_END_ALLOW_THREADS
        if (rv == -1) {
            if (errno == EAGAIN) {      /* buffer is full, try again */
                errno = 0;
                continue;
            } else                      /* it's a real error */
                return PyErr_SetFromErrno(PyExc_IOError);
        } else {                        /* wrote rv bytes */
            self->ocount += rv;
            size -= rv;
            cp += rv;
        }
    }
    Py_INCREF(Py_None);
    return Py_None;
}
コード例 #2
0
ファイル: ossaudiodev.c プロジェクト: M31MOTH/cpython
static PyObject *
oss_writeall(oss_audio_t *self, PyObject *args)
{
    Py_buffer data;
    const char *cp;
    Py_ssize_t size;
    Py_ssize_t rv;
    fd_set write_set_fds;
    int select_rv;

    /* NB. writeall() is only useful in non-blocking mode: according to
       Guenter Geiger <*****@*****.**> on the linux-audio-dev list
       (http://eca.cx/lad/2002/11/0380.html), OSS guarantees that
       write() in blocking mode consumes the whole buffer.  In blocking
       mode, the behaviour of write() and writeall() from Python is
       indistinguishable. */

    if (!_is_fd_valid(self->fd))
        return NULL;

    if (!PyArg_ParseTuple(args, "y*:writeall", &data))
        return NULL;

    if (!_PyIsSelectable_fd(self->fd)) {
        PyErr_SetString(PyExc_ValueError,
                        "file descriptor out of range for select");
        PyBuffer_Release(&data);
        return NULL;
    }
    /* use select to wait for audio device to be available */
    FD_ZERO(&write_set_fds);
    FD_SET(self->fd, &write_set_fds);
    cp = (const char *)data.buf;
    size = data.len;

    while (size > 0) {
        Py_BEGIN_ALLOW_THREADS
        select_rv = select(self->fd+1, NULL, &write_set_fds, NULL, NULL);
        Py_END_ALLOW_THREADS

        assert(select_rv != 0);   /* no timeout, can't expire */
        if (select_rv == -1) {
            PyBuffer_Release(&data);
            return PyErr_SetFromErrno(PyExc_OSError);
        }

        rv = _Py_write(self->fd, cp, Py_MIN(size, INT_MAX));
        if (rv == -1) {
            /* buffer is full, try again */
            if (errno == EAGAIN) {
                PyErr_Clear();
                continue;
            }
            /* it's a real error */
            PyBuffer_Release(&data);
            return NULL;
        }

        /* wrote rv bytes */
        self->ocount += rv;
        size -= rv;
        cp += rv;
    }
    PyBuffer_Release(&data);
    Py_RETURN_NONE;
}