/*
 * 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"'

    def parse_arg(self, argname, displayname):
        return """
            {paramname} = PyLong_AsVoidPtr({argname});
            if (!{paramname} && PyErr_Occurred()) {{{{
                goto exit;
            }}}}
            """.format(argname=argname, paramname=self.parser_name)

[python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=3e537d244034affb]*/

/*[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)
{
#ifdef HAVE_MP_SEMAPHORE

    PyTypeObject *semlock_type = (PyTypeObject *)PyType_FromModuleAndSpec(
                module, &_PyMp_SemLockType_spec, NULL);

    if (semlock_type == NULL) {
        return -1;
    }
    int rc = PyModule_AddType(module, semlock_type);
    Py_DECREF(semlock_type);
    if (rc < 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(semlock_type->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_size = 0,
    .m_methods = module_methods,
    .m_slots = multiprocessing_slots,
};

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