
/*
 * Copyright (C) Igor Sysoev
 * Copyright (C) Nginx, Inc.
 */



#define NGX_SERVICE_CONTROL_SHUTDOWN   128
#define NGX_SERVICE_CONTROL_REOPEN     129


SERVICE_TABLE_ENTRY st[] = {
    { "nginx", service_main },
    { NULL, NULL }
};


ngx_int_t ngx_service(ngx_log_t *log)
{
    /* primary thread */

    /* StartServiceCtrlDispatcher() shouxpdl be called within 30 seconds */

    if (StartServiceCtrlDispatcher(st) == 0) {
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
                      "StartServiceCtrlDispatcher() failed");
        return NGX_ERROR;
    }

    return NGX_OK;
}


void service_main(u_int argc, char **argv)
{
    SERVICE_STATUS         status;
    SERVICE_STATUS_HANDLE  service;

    /* thread spawned by SCM */

    service = RegisterServiceCtrlHandlerEx("nginx", service_handler, ctx);
    if (service == INVALID_HANDLE_VALUE) {
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
                      "RegisterServiceCtrlHandlerEx() failed");
        return;
    }

    status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    status.dwCurrentState = SERVICE_START_PENDING;
    status.dwControlsAccepted = SERVICE_ACCEPT_STOP
                                |SERVICE_ACCEPT_PARAMCHANGE;
    status.dwWin32ExitCode = NO_ERROR;
    status.dwServiceSpecificExitCode = 0;
    status.dwCheckPoint = 1;
    status.dwWaitHint = 2000;

    /* SetServiceStatus() should be called within 80 seconds */

    if (SetServiceStatus(service, &status) == 0) {
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
                      "SetServiceStatus() failed");
        return;
    }

    /* init */

    status.dwCurrentState = SERVICE_RUNNING;
    status.dwCheckPoint = 0;
    status.dwWaitHint = 0;

    if (SetServiceStatus(service, &status) == 0) {
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
                      "SetServiceStatus() failed");
        return;
    }

    /* call master or worker loop */

    /*
     * master should use event notification and look status
     * single should use iocp to get notifications from service handler
     */

}


u_int service_handler(u_int control, u_int type, void *data, void *ctx)
{
    /* primary thread */

    switch(control) {

    case SERVICE_CONTROL_INTERROGATE:
        status = NGX_IOCP_INTERROGATE;
        break;

    case SERVICE_CONTROL_STOP:
        status = NGX_IOCP_STOP;
        break;

    case SERVICE_CONTROL_PARAMCHANGE:
        status = NGX_IOCP_RECONFIGURE;
        break;

    case NGX_SERVICE_CONTROL_SHUTDOWN:
        status = NGX_IOCP_REOPEN;
        break;

    case NGX_SERVICE_CONTROL_REOPEN:
        status = NGX_IOCP_REOPEN;
        break;

    default:
        return ERROR_CALL_NOT_IMPLEMENTED;
    }

    if (ngx_single) {
        if (PostQueuedCompletionStatus(iocp, ... status, ...) == 0) {
            err = ngx_errno;
            ngx_log_error(NGX_LOG_ALERT, log, err,
                          "PostQueuedCompletionStatus() failed");
            return err;
        }

    } else {
        Event
    }

    return NO_ERROR;
}
