/*
**	$VER: daemon.c 1.0 (02.11.94)
**
**	start & stop a daemon process in a shared library
**
**	© Copyright 1994 by Norbert Püschel
**	All Rights Reserved
*/

#include "daemon.h"

#include <dos/dostags.h>

void InitDaemon(volatile struct Daemon *dm)

{
  InitSemaphore((struct SignalSemaphore *)&dm->dm_Sync);
  dm->dm_Process = 0;
  dm->dm_Signal = -1;
  dm->dm_Startup = 0;
}

BOOL StartDaemon(volatile struct Daemon *dm,void (*func)(void),STRPTR name,BYTE pri)

{
  Forbid();
  if(dm->dm_Process == 0) {
    dm->dm_Process = CreateNewProcTags(NP_Entry,func,
                                       NP_Name,name,
                                       NP_Priority,pri,
                                       NP_WindowPtr,-1,
                                       TAG_DONE);
    if(dm->dm_Process) {
      DoPkt1((struct MsgPort *)&dm->dm_Process->pr_MsgPort,0,(LONG)dm);
    }
  }
  Permit();

  return((BOOL)(dm->dm_Process != 0));
}

void StopDaemon(volatile struct Daemon *dm)

{
  Forbid();
  if(dm->dm_Process) {
    Signal((struct Task *)(dm->dm_Process),1L << dm->dm_Signal);
    
    ObtainSemaphore((struct SignalSemaphore *)&dm->dm_Sync);
    ReleaseSemaphore((struct SignalSemaphore *)&dm->dm_Sync);

    dm->dm_Process = 0;
    dm->dm_Signal = -1;
    dm->dm_Startup = 0;
  }
  Permit();
}

volatile struct Daemon *DaemonInit(void)

{
  volatile struct Daemon *dm;
  struct DosPacket *startup;

  startup = WaitPkt();

  dm = (volatile struct Daemon *)startup->dp_Arg1;

  dm->dm_Signal = AllocSignal(-1);
  dm->dm_Startup = startup;

  return(dm);
}

void DaemonInitOK(volatile struct Daemon *dm)

{
  ObtainSemaphore((struct SignalSemaphore *)&dm->dm_Sync);
  PutMsg(dm->dm_Startup->dp_Port,dm->dm_Startup->dp_Link);
  dm->dm_Startup = 0;
}

void DaemonExit(volatile struct Daemon *dm)

{
  if(dm->dm_Signal != -1) FreeSignal(dm->dm_Signal);
  Forbid();
  if(dm->dm_Startup) {
    PutMsg(dm->dm_Startup->dp_Port,dm->dm_Startup->dp_Link);
    dm->dm_Startup = 0;
  }
  else {
    ReleaseSemaphore((struct SignalSemaphore *)&dm->dm_Sync);
  }
}
