/*************************************************

DML_process.h

Description:
        Introduces the DML_process class. This is a base class from
        which the DML_child and DML_master classes inherit.                             
                                
Author: Ryan Findley


History:
who     when            what
--------------------------------
ryan    7/28/99         started
                        attempted to implement it all inline.
                        seems to have worked.
ryan	7/29/99			added checkMsgBackup
ryan`	7/29/99			added constructors/destructor
ryan	8/25/99			added fork.
***************************************************/

#ifndef DML_PROCESS_H
#define DML_PROCESS_H


#include <process.h>
#include <sys/psinfo.h>
#include <sys/types.h>
#include <sys/kernel.h>
#include <signal.h>
#include <string.h>

#define PROC_DNE -1
#define FORK_CHILD 1
#define FORK_MASTER 2
#define FORK_FAIL -1

class DML_process
{
  public:
    //data
    pid_t pid;
    int priority;
    
    //conversions   
    operator pid_t();

    //member functions
	DML_process();								//default constructor
	DML_process(	const char *, 
					const nid_t theNid = 0);	//constructor: make this process from the qnx_name server.
	
	int fork();									//starts a new process by forking. 
												//Returns FORK_CHILD if the forked child, FORK_MASTER, or FORK_FAIL.
	
    send( const int );                          //send an int (no response necessary)
    send( const void *, const size_t );         //send arbitrary data (no response necessary)
    pid_t receive( int & );                     //receive an int. replies automatically.
    pid_t receive( void *, size_t );            //receive arbitrary data. replies automatically.
    slay( const int whatSignal = SIGTERM );     //kill (or other signal)
    kill( const int whatSignal = SIGTERM );     //same as slay
    void * poll( void *,size_t );               //returns NULL immediately if no msg present.
	int checkMsgBackup();						//returns PROC_DNE (process Does Not Exist) if pid is not valid.
      
    //operators
    
    // << operator: same as send.
    DML_process & operator << (const int);
    DML_process & operator << (const char *);
    DML_process & operator << (const char);
    DML_process & operator << (const float);
    DML_process & operator << (const double);
    DML_process & operator << (const long);

    // >> operator: same as receive.
    DML_process & operator >> (int &);
    DML_process & operator >> (char *);
    DML_process & operator >> (char &);
    DML_process & operator >> (float &);
    DML_process & operator >> (double &);
    DML_process & operator >> (long &);
	
  private:
	nid_t nodeID;								//node on which the process is running
} ;



//inline functions
inline DML_process::operator pid_t() 
{    return(pid);  }

inline DML_process::send(const int theMsg)
{   
	int msg = theMsg;
	Send(pid, &msg, 0, sizeof(msg), 0);   }

inline DML_process::send(const void * data, const size_t sz)
{
    Send(pid, data, 0, sz, 0);
}

pid_t inline DML_process::receive(int & rmsg)
{    
    if ( Receive(pid,&rmsg,sizeof(rmsg)) != -1 )
    {
        Reply(pid,0,0);
        return(pid);
    }
    else
        return(-1);
}

pid_t inline DML_process::receive(void *data, size_t sz)
{    
    if ( Receive(pid,data,sz) != -1 )
    {
        Reply(pid,0,0);
        return(pid);
    }
    else
        return(-1);
}

inline int DML_process::slay(const int whichSignal)
{    return (::kill(pid,whichSignal));    }

inline int DML_process::kill(const int whichSignal)
{    return (::kill(pid,whichSignal));    }

inline void * DML_process::poll(void *data, size_t sz)
{
    if ( Creceive(pid,data,sz) )
        return(data);
    else
        return(NULL);
}
        
//inline operators
inline DML_process & DML_process::operator <<(const int msg)    {    send(msg);                 return(*this);   }
inline DML_process & DML_process::operator <<(const char * msg) {    send(msg,strlen(msg));     return(*this);   }
inline DML_process & DML_process::operator <<(const char msg)   {    send(&msg,sizeof(msg));    return(*this);   }
inline DML_process & DML_process::operator <<(const float msg)  {    send(&msg,sizeof(msg));    return(*this);   }
inline DML_process & DML_process::operator <<(const double msg) {    send(&msg,sizeof(msg));    return(*this);   }
inline DML_process & DML_process::operator <<(const long msg)   {    send(&msg,sizeof(msg));    return(*this);   }

inline DML_process & DML_process::operator >>(int & msg)        {    receive(msg);              return(*this);   }
inline DML_process & DML_process::operator >>(char * msg)       {    receive(msg,strlen(msg));  return(*this);   }
inline DML_process & DML_process::operator >>(char & msg)       {    receive(&msg,sizeof(msg)); return(*this);   }
inline DML_process & DML_process::operator >>(float & msg)      {    receive(&msg,sizeof(msg)); return(*this);   }
inline DML_process & DML_process::operator >>(double & msg)     {    receive(&msg,sizeof(msg)); return(*this);   }
inline DML_process & DML_process::operator >>(long & msg)       {    receive(&msg,sizeof(msg)); return(*this);   }
    
#endif //DML_PROCESS_H;
