#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#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);

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

    return NULL;
}

void
IMScheduler_MTPC::
send_request(
    IMScheduler_send_handler *pimsh
)
{
    pimsh->send();
}

int
IMScheduler_MTPC::
start()
{
    IMState *pims;
    pthread_t th;
    pthread_attr_t attr;

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

    for (;;) {
	pims = pimp->accept();
	if (pims) {
	    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: */
