/*
 * Extension module used by multiprocessing package
 *
 * multiprocessing.c
 *
 * Copyright (c) 2006-2008, R Oudkerk
 * Licensed to PSF under a Contributor Agreement.
 */

#include "multiprocessing.h"

/*[python input]
class HANDLE_converter(CConverter):
    type = "HANDLE"
    format_unit = '"F_HANDLE"'

[python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=9fad6080b79ace91]*/

/*[clinic input]
module _multiprocessing
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=01e0745f380ac6e3]*/

#include "clinic/multiprocessing.c.h"

/*
 * Function which raises exceptions based on error codes
 */

PyObject *
_PyMp_SetError(PyObject *Type, int num)
{
    switch (num) {
#ifdef MS_WINDOWS
    case MP_STANDARD_ERROR:
        if (Type == NULL)
            Type = PyExc_OSError;
        PyErr_SetExcFromWindowsErr(Type, 0);
        break;
    case MP_SOCKET_ERROR:
        if (Type == NULL)
            Type = PyExc_OSError;
        PyErr_SetExcFromWindowsErr(Type, WSAGetLastError());
        break;
#else /* !MS_WINDOWS */
    case MP_STANDARD_ERROR:
    case MP_SOCKET_ERROR:
        if (Type == NULL)
            Type = PyExc_OSError;
        PyErr_SetFromErrno(Type);
        break;
#endif /* !MS_WINDOWS */
    case MP_MEMORY_ERROR:
        PyErr_NoMemory();
        break;
    case MP_EXCEPTION_HAS_BEEN_SET:
        break;
    default:
        PyErr_Format(PyExc_RuntimeError,
                     "unknown error number %d", num);
    }
    return NULL;
}

#ifdef MS_WINDOWS
/*[clinic input]
_multiprocessing.closesocket

    handle: HANDLE
    /

[clinic start generated code]*/

static PyObject *
_multiprocessing_closesocket_impl(PyObject *module, HANDLE handle)
/*[clinic end generated code: output=214f359f900966f4 input=8a20706dd386c6cc]*/
{
    int ret;

    Py_BEGIN_ALLOW_THREADS
    ret = closesocket((SOCKET) handle);
    Py_END_ALLOW_THREADS

    if (ret)
        return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
    Py_RETURN_NONE;
}

/*[clinic input]
_multiprocessing.recv

    handle: HANDLE
    size: int
    /

[clinic start generated code]*/

static PyObject *
_multiprocessing_recv_impl(PyObject *module, HANDLE handle, int size)
/*[clinic end generated code: output=92322781ba9ff598 input=6a5b0834372cee5b]*/
{
    int nread;
    PyObject *buf;

    buf = PyBytes_FromStringAndSize(NULL, size);
    if (!buf)
        return NULL;

    Py_BEGIN_ALLOW_THREADS
    nread = recv((SOCKET) handle, PyBytes_AS_STRING(buf), size, 0);
    Py_END_ALLOW_THREADS

    if (nread < 0) {
        Py_DECREF(buf);
        return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
    }
    _PyBytes_Resize(&buf, nread);
    return buf;
}

/*[clinic input]
_multiprocessing.send

    handle: HANDLE
    buf: Py_buffer
    /

[clinic start generated code]*/

static PyObject *
_multiprocessing_send_impl(PyObject *module, HANDLE handle, Py_buffer *buf)
/*[clinic end generated code: output=52d7df0519c596cb input=41dce742f98d2210]*/
{
    int ret, length;

    length = (int)Py_MIN(buf->len, INT_MAX);

    Py_BEGIN_ALLOW_THREADS
    ret = send((SOCKET) handle, buf->buf, length, 0);
    Py_END_ALLOW_THREADS

    if (ret < 0)
        return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
    return PyLong_FromLong(ret);
}

#endif

/*[clinic input]
_multiprocessing.sem_unlink

    name: str
    /

[clinic start generated code]*/

static PyObject *
_multiprocessing_sem_unlink_impl(PyObject *module, const char *name)
/*[clinic end generated code: output=fcbfeb1ed255e647 input=bf939aff9564f1d5]*/
{
    return _PyMp_sem_unlink(name);
}

/*
 * Function table
 */

static PyMethodDef module_methods[] = {
#ifdef MS_WINDOWS
    _MULTIPROCESSING_CLOSESOCKET_METHODDEF
    _MULTIPROCESSING_RECV_METHODDEF
    _MULTIPROCESSING_SEND_METHODDEF
#endif
#if !defined(POSIX_SEMAPHORES_NOT_ENABLED) && !defined(__ANDROID__)
    _MULTIPROCESSING_SEM_UNLINK_METHODDEF
#endif
    {NULL}
};


/*
 * Initialize
 */

static int
multiprocessing_exec(PyObject *module)
{
#if defined(MS_WINDOWS) ||                                              \
  (defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED))

    /* Add _PyMp_SemLock type to module */
    if (PyModule_AddType(module, &_PyMp_SemLockType) < 0) {
        return -1;
    }

    {
        PyObject *py_sem_value_max;
        /* Some systems define SEM_VALUE_MAX as an unsigned value that
         * causes it to be negative when used as an int (NetBSD).
         *
         * Issue #28152: Use (0) instead of 0 to fix a warning on dead code
         * when using clang -Wunreachable-code. */
        if ((int)(SEM_VALUE_MAX) < (0))
            py_sem_value_max = PyLong_FromLong(INT_MAX);
        else
            py_sem_value_max = PyLong_FromLong(SEM_VALUE_MAX);

        if (py_sem_value_max == NULL) {
            return -1;
        }
        if (PyDict_SetItemString(_PyMp_SemLockType.tp_dict, "SEM_VALUE_MAX",
                             py_sem_value_max) < 0) {
            Py_DECREF(py_sem_value_max);
            return -1;
        }
        Py_DECREF(py_sem_value_max);
    }

#endif

    /* Add configuration macros */
    PyObject *flags = PyDict_New();
    if (!flags) {
        return -1;
    }

#define ADD_FLAG(name)                                          \
    do {                                                        \
        PyObject *value = PyLong_FromLong(name);                \
        if (value == NULL) {                                    \
            Py_DECREF(flags);                                   \
            return -1;                                          \
        }                                                       \
        if (PyDict_SetItemString(flags, #name, value) < 0) {    \
            Py_DECREF(flags);                                   \
            Py_DECREF(value);                                   \
            return -1;                                          \
        }                                                       \
        Py_DECREF(value);                                       \
    } while (0)

#if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED)
    ADD_FLAG(HAVE_SEM_OPEN);
#endif
#ifdef HAVE_SEM_TIMEDWAIT
    ADD_FLAG(HAVE_SEM_TIMEDWAIT);
#endif
#ifdef HAVE_BROKEN_SEM_GETVALUE
    ADD_FLAG(HAVE_BROKEN_SEM_GETVALUE);
#endif
#ifdef HAVE_BROKEN_SEM_UNLINK
    ADD_FLAG(HAVE_BROKEN_SEM_UNLINK);
#endif

    if (PyModule_AddObject(module, "flags", flags) < 0) {
        Py_DECREF(flags);
        return -1;
    }

    return 0;
}

static PyModuleDef_Slot multiprocessing_slots[] = {
    {Py_mod_exec, multiprocessing_exec},
    {0, NULL}
};

static struct PyModuleDef multiprocessing_module = {
    PyModuleDef_HEAD_INIT,
    .m_name = "_multiprocessing",
    .m_methods = module_methods,
    .m_slots = multiprocessing_slots,
};

PyMODINIT_FUNC
PyInit__multiprocessing(void)
{
    return PyModuleDef_Init(&multiprocessing_module);
}
