#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_SIGNAL
#include <signal.h>
#endif
#include "IMScheduler_MTPC.hh"
#include "IMProtocol.hh"
#include "IMState.hh"

struct IMScheduler_thread_arg {
    IMProtocol *pimp;
    IMState *pimstate;
};

extern "C" void* IMScheduler_MTPC_thread_entry(void *priv);
void* IMScheduler_MTPC_thread_entry(
    void *priv
)
{
    IMScheduler_thread_arg *pa = (IMScheduler_thread_arg *) priv;
    IMProtocol *pimp = pa->pimp;
    IMState *pims = pa->pimstate;

    free(pa);

#ifdef HAVE_SIGNAL
    // block signal handling
    sigset_t sset;
    sigfillset(&sset);
    pthread_sigmask(SIG_BLOCK, &sset, NULL);
#endif

    for(;;) {
	if (!pimp->receive_and_dispatch(pims))
	    break;
    }

    return NULL;
}

int
IMScheduler_MTPC::
start(
    IMAccept *pimaccept,
    IMProtocol *pimp,
    IMState *pims
)
{
    pthread_t th;
    pthread_attr_t attr;

    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);


    IMScheduler_thread_arg *pima;
    pima = (IMScheduler_thread_arg*) malloc(sizeof(IMScheduler_thread_arg));
    if (!pima) return 0;
    pima->pimp = pimp;
    pima->pimstate = pims;
    pthread_create(&th, &attr, IMScheduler_MTPC_thread_entry, pima);

    return 1;
}

int
IMScheduler_MTPC::
stop()
{
    return 1;
}

IMScheduler_MTPC::IMScheduler_MTPC()
    : IMScheduler()
{
}

IMScheduler_MTPC*
IMScheduler_MTPC::construct()
{
    IMScheduler_MTPC *pimsch = new IMScheduler_MTPC();
    pimsch->register_singleton();

    return pimsch;
}


/* Local Variables: */
/* c-file-style: "iiim-project" */
/* End: */
