#include "apr_arch_threadproc.h"
#include "apr_strings.h"
#include "apr_portable.h"
#include "apr_signal.h"

apr_status_t os9_thread_proc_wait(apr_proc_t *proc,
                                  int *exitcode, apr_exit_why_e *exitwhy,
                                  apr_wait_how_e waithow)
{
    pid_t pstatus;
    int waitpid_options = 0;
    int exit_int;
    int ignore;
    apr_exit_why_e ignorewhy;
	apr_status_t stat;

    if (exitcode == NULL) {
        exitcode = &ignore;
    }

    if (exitwhy == NULL) {
        exitwhy = &ignorewhy;
    }

    if (waithow != APR_WAIT) {
        waitpid_options |= WNOHANG;
    }

	pstatus = waitpid(proc->pid, &exit_int, waitpid_options);
	if (((int)pstatus) > 0) {
        proc->pid = pstatus;

        if (WIFEXITED(exit_int)) {
            *exitwhy = APR_PROC_EXIT;
            *exitcode = WEXITSTATUS(exit_int);
        }
        else if (WIFSIGNALED(exit_int)) {
            *exitwhy = APR_PROC_SIGNAL;
            *exitcode = WTERMSIG(exit_int);
        }
        else {
            /* unexpected condition */
            return APR_EGENERAL;
        }
        return APR_CHILD_DONE;
    }
	return APR_SUCCESS;
}

#ifndef TRUE
#define TRUE (1)
#define FALSE (0)
#endif

pthread_mutex_t io_mutex;	/* Thread Lock for starting processes */
unsigned int io_mutex_init = FALSE;
void lock_register(void *addr, int num, u_int32 caller);

error_code io_mutex_lock(int i)
{
	error_code err;
	u_int32 caller = 0;
#if defined(_MPFPOWERPC)
	_asm(" lwz %0,0(r1)\n lwz %0,4(%0)", __obj_assign(__reg_base(caller)));
#endif

	if (io_mutex_init == FALSE)
	{
		/* Init the Mutex Lock the first time */
		pthread_mutexattr_t attr;
		pthread_mutexattr_init(&attr);
		pthread_mutex_init(&io_mutex,&attr);
		io_mutex_init = TRUE;
	}
#ifdef MUTEX_LOG
	lock_register(&io_mutex, i+0x100,caller);
#endif
	err = pthread_mutex_lock(&io_mutex);
#ifdef MUTEX_LOG
	lock_register(&io_mutex, i+0x200,caller);
#endif
	return err;
}

error_code io_mutex_unlock(int i)
{
	error_code err;
	u_int32 caller = 0;
#if defined(_MPFPOWERPC)
	_asm(" lwz %0,0(r1)\n lwz %0,4(%0)", __obj_assign(__reg_base(caller)));
#endif

#ifdef MUTEX_LOG
	lock_register(&io_mutex, i+0x300,caller);
#endif
	err = pthread_mutex_unlock(&io_mutex);
	return err;
}
