/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "fcgid_proctbl.h"
#include "apr_version.h"
#include "apr_shm.h"
#include "apr_global_mutex.h"
#include "fcgid_global.h"
#include "fcgid_conf.h"
#include "unixd.h"
#include <unistd.h>

#if MODULE_MAGIC_NUMBER_MAJOR < 20081201
#define ap_unixd_set_global_mutex_perms unixd_set_global_mutex_perms
#endif

static apr_shm_t *g_sharemem = NULL;
static apr_global_mutex_t *g_sharelock = NULL;
char g_sharelock_name[L_tmpnam];
static fcgid_procnode *g_proc_array = NULL; /* Contain all process slot */
static fcgid_procnode *g_free_list_header = NULL;   /* Attach to no process list */
static fcgid_procnode *g_busy_list_header = NULL;   /* Attach to a working process list */
static fcgid_procnode *g_idle_list_header = NULL;   /* Attach to an idle process list */
static fcgid_procnode *g_error_list_header = NULL;  /* Attach to an error process list */
static fcgid_share *_global_memory = NULL;
static fcgid_global_share *g_global_share = NULL;   /* global information */
static size_t g_table_size = FCGID_PROC_TABLE_SIZE;

/* apr version 0.x not support apr_shm_remove, I have to copy it from apr version 1.x */
#if (APR_MAJOR_VERSION < 1)
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#ifdef HAVE_SYS_IPC_H
#include <sys/ipc.h>
#endif
#ifdef HAVE_SYS_MUTEX_H
#include <sys/mutex.h>
#endif
#ifdef HAVE_SYS_SHM_H
#include <sys/shm.h>
#endif
#if !defined(SHM_R)
#define SHM_R 0400
#endif
#if !defined(SHM_W)
#define SHM_W 0200
#endif
#ifdef HAVE_SYS_FILE_H
#include <sys/file.h>
#endif

static apr_status_t apr_shm_remove(const char *filename, apr_pool_t * pool)
{
#if APR_USE_SHMEM_SHMGET
    apr_status_t status;
    apr_file_t *file;
    key_t shmkey;
    int shmid;
#endif

#if APR_USE_SHMEM_MMAP_TMP
    return apr_file_remove(filename, pool);
#endif
#if APR_USE_SHMEM_MMAP_SHM
    if (shm_unlink(filename) == -1) {
        return errno;
    }
    return APR_SUCCESS;
#endif
#if APR_USE_SHMEM_SHMGET
    /* Presume that the file already exists; just open for writing */
    status = apr_file_open(&file, filename, APR_WRITE,
                           APR_OS_DEFAULT, pool);
    if (status) {
        return status;
    }

    /* ftok() (on solaris at least) requires that the file actually
     * exist before calling ftok(). */
    shmkey = ftok(filename, 1);
    if (shmkey == (key_t) - 1) {
        goto shm_remove_failed;
    }

    apr_file_close(file);

    if ((shmid = shmget(shmkey, 0, SHM_R | SHM_W)) < 0) {
        goto shm_remove_failed;
    }

    /* Indicate that the segment is to be destroyed as soon
     * as all processes have detached. This also disallows any
     * new attachments to the segment. */
    if (shmctl(shmid, IPC_RMID, NULL) == -1) {
        goto shm_remove_failed;
    }
    return apr_file_remove(filename, pool);

  shm_remove_failed:
    status = errno;
    /* ensure the file has been removed anyway. */
    apr_file_remove(filename, pool);
    return status;
#endif

    /* No support for anonymous shm */
    return APR_ENOTIMPL;
}
#endif                          /* APR_MAJOR_VERSION<1 */

apr_status_t
proctable_post_config(server_rec * main_server, apr_pool_t * configpool)
{
    size_t shmem_size = sizeof(fcgid_share);
    fcgid_procnode *ptmpnode = NULL;
    int i;
    apr_status_t rv;
    fcgid_server_conf *sconf = ap_get_module_config(main_server->module_config,
                                                    &fcgid_module);

    /* Remove share memory first */
    apr_shm_remove(sconf->shmname_path, main_server->process->pconf);

    /* Create share memory */
    if ((rv = apr_shm_create(&g_sharemem, shmem_size, sconf->shmname_path,
                             main_server->process->pconf)) != APR_SUCCESS)
    {
        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
                     "mod_fcgid: Can't create shared memory for size %" APR_SIZE_T_FMT " bytes",
                     shmem_size);
        exit(1);
    }
    _global_memory = apr_shm_baseaddr_get(g_sharemem);

    /* Create global mutex */
    if ((rv =
         apr_global_mutex_create(&g_sharelock, tmpnam(g_sharelock_name),
                                 APR_LOCK_DEFAULT,
                                 main_server->process->pconf)) !=
        APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
                     "mod_fcgid: Can't create global mutex");
        exit(1);
    }
    if ((rv = ap_unixd_set_global_mutex_perms(g_sharelock)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
                     "mod_fcgid: Can't set global mutex perms");
        exit(1);
    }

    memset(_global_memory, 0, shmem_size);
    g_proc_array = _global_memory->procnode_array;
    g_global_share = &_global_memory->global;

    g_global_share->must_exit = 0;

    /* Init the array */
    g_idle_list_header = g_proc_array;
    g_busy_list_header = g_idle_list_header + 1;
    g_error_list_header = g_busy_list_header + 1;
    g_free_list_header = g_error_list_header + 1;
    ptmpnode = g_free_list_header;
    for (i = 0; i < FCGID_MAX_APPLICATION; i++) {
        ptmpnode->next_index = ptmpnode - g_proc_array + 1;
        ptmpnode++;
    }

    return APR_SUCCESS;
}

apr_status_t
proctable_child_init(server_rec * main_server, apr_pool_t * configpool)
{
    apr_status_t rv;

    if ((rv = apr_global_mutex_child_init(&g_sharelock,
                                          g_sharelock_name,
                                          main_server->process->pconf)) !=
        APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
                     "mod_fcgid: apr_global_mutex_child_init error");
        exit(1);
    }

    return rv;
}

apr_status_t proctable_lock_table(void)
{
    return apr_global_mutex_lock(g_sharelock);
}

apr_status_t proctable_unlock_table(void)
{
    return apr_global_mutex_unlock(g_sharelock);
}

fcgid_procnode *proctable_get_free_list(void)
{
    return g_free_list_header;
}

fcgid_procnode *proctable_get_busy_list(void)
{
    return g_busy_list_header;
}

fcgid_procnode *proctable_get_idle_list(void)
{
    return g_idle_list_header;
}

fcgid_procnode *proctable_get_table_array(void)
{
    return g_proc_array;
}

fcgid_procnode *proctable_get_error_list(void)
{
    return g_error_list_header;
}

fcgid_global_share *proctable_get_globalshare(void)
{
    return g_global_share;
}

size_t proctable_get_table_size(void)
{
    return g_table_size;
}

void safe_lock(server_rec * s)
{
    apr_status_t rv;

    if (g_global_share->must_exit) {
        ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
                     "mod_fcgid: server is restarted, pid %" APR_PID_T_FMT
                     " must exit",
                     getpid());
        kill(getpid(), SIGTERM);
    }

    /* Lock error is a fatal error */
    if ((rv = proctable_lock_table()) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
                     "mod_fcgid: can't get lock in pid %" APR_PID_T_FMT,
                     getpid());
        exit(1);
    }
}

void safe_unlock(server_rec * s)
{
    /* Lock error is a fatal error */
    apr_status_t rv;

    if ((rv = proctable_unlock_table()) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
                     "mod_fcgid: can't unlock in pid %" APR_PID_T_FMT, 
                     getpid());
        exit(1);
    }
}

void proctable_print_debug_info(server_rec * main_server)
{
    int freecount = 0;
    fcgid_procnode *current_node;

    for (current_node = &g_proc_array[g_free_list_header->next_index];
         current_node != g_proc_array;
         current_node = &g_proc_array[current_node->next_index])
        freecount++;

    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, main_server,
                 "mod_fcgid: total node count: %d, free node count: %d",
                 FCGID_MAX_APPLICATION, freecount);

    for (current_node = &g_proc_array[g_idle_list_header->next_index];
         current_node != g_proc_array;
         current_node = &g_proc_array[current_node->next_index]) {
        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, main_server,
                     "mod_fcgid: idle node index: %ld",
                     (long)(current_node - g_proc_array));
    }

    for (current_node = &g_proc_array[g_busy_list_header->next_index];
         current_node != g_proc_array;
         current_node = &g_proc_array[current_node->next_index]) {
        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, main_server,
                     "mod_fcgid: busy node index: %ld",
                     (long)(current_node - g_proc_array));
    }

    for (current_node = &g_proc_array[g_error_list_header->next_index];
         current_node != g_proc_array;
         current_node = &g_proc_array[current_node->next_index]) {
        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, main_server,
                     "mod_fcgid: error node index: %ld",
                     (long)(current_node - g_proc_array));
    }
}
