/*en    Laurent Constantin's network library (lcrzo)
                 lcrzo_process module

  Process(unix) and thread(Windows) functions.
*/
/*fr    Bibliotheque reseau de Laurent Constantin (lcrzo)
                 Module lcrzo_process

  Les fonctions presentes dans ce module assurent la gestion de
  processus(unix) ou threads(Windows).
*/

/*-------------------------------------------------------------*/
/*EN************************************************************
 * Note about processes and threads :                          *
 *  - Under Unix, a process is created (fork).                 *
 *  - Under Windows, it's not possible to use a process, so a  *
 *    thread is created. In this case, we have to take care    *
 *    about global variables and static variables.             *
 ***************************************************************/
/*FR************************************************************
 * Note sur les processus et les threads :                     *
 *  - Sous Unix, un processus est cree (fork).                 *
 *  - Sous Windows, ce n'est pas possible d'employer des       *
 *    processus, donc un thread est cree. Dans ce cas, il faut *
 *    prendre garde aux variables globales et statiques.       *
 ***************************************************************/

/*-------------------------------------------------------------*/
/*en definition of a lcrzo_process. You should not use its
   fields directly. */
/*fr definition d'un lcrzo_process. Vous ne devriez pas utiliser
   directement ses champs. */
typedef struct
{ lcrzo_uint32 processid;
  lcrzo_uint32 threadid;
  void *threadhandle;
  lcrzo_data pfuncinfos;
  lcrzo_bool hasended;
  int returnedvalue;
  int (*punixreturn_uint82int)(lcrzo_uint8 ret);
} lcrzo_process;

/*-------------------------------------------------------------*/
/*en Name : lcrzo_process_current_init
   Description :
     Initialize a lcrzo_process to contain the current process.
   Input parameter(s) :
   Input/output parameter(s) :
   Output parameter(s) :
     *pprocess : lcrzo_process containing the current process
   Normal return values :
     LCRZO_ERR_OK : ok
*/
/*fr Nom : lcrzo_process_current_init
   Description :
     Initialise un lcrzo_process afin qu'il contienne le processus
     courant.
   Parametre(s) d'entree :
   Parametre(s) d'entree-sortie :
   Parametre(s) de sortie :
     *pprocess : lcrzo_process qui contient le processus courant
   Valeurs de retour normales :
     LCRZO_ERR_OK : ok
*/
int lcrzo_process_current_init(lcrzo_process *pprocess);

/*-------------------------------------------------------------*/
/*en Name : lcrzo_process_current_exit
   Description :
     Leave the current process.
     Warning : under Unix, returnvalue is truncated to 8 bits.
               Functions lcrzo_process_other_init2 and 
	       lcrzo_process_int2uint8_std might be
               of interest if this a problem for your code.
   Input parameter(s) :
     returnvalue : value returned by the process
   Input/output parameter(s) :
   Output parameter(s) :
   Normal return values :
     LCRZO_ERR_OK : ok
*/
/*fr Nom : lcrzo_process_current_exit
   Description :
     Quitte le processus courant.
     Attention : sous Unix, returnvalue est tronque a 8 bits.
                 Les fonctions lcrzo_process_other_init2 and 
	         lcrzo_process_int2uint8_std peuvent vous aider
		 si cela pose un probleme pour votre code.
   Parametre(s) d'entree :
     returnvalue : valeur retournee par le processus
   Parametre(s) d'entree-sortie :
   Parametre(s) de sortie :
   Valeurs de retour normales :
     LCRZO_ERR_OK : ok
*/
int lcrzo_process_current_exit(int returnvalue);

/*-------------------------------------------------------------*/
/*en Name : lcrzo_process_current_priority_set
   Description :
     Change the priority level of the current process.
   Input parameter(s) :
     priority : priority to set :
                    -127 = low priority
                      0  = normal priority
                    +127 = high priority (need to be admin)
   Input/output parameter(s) :
   Output parameter(s) :
   Normal return values :
     LCRZO_ERR_OK : ok
*/
/*fr Nom : lcrzo_process_current_priority_set
   Description :
     Change le niveau de priorite du processus courant.
   Parametre(s) d'entree :
     priority : priorite a affecter :
                    -127 = faible priorite
                      0  = priorite normale
                    +127 = priorite haute (necessite d'etre root)
   Parametre(s) d'entree-sortie :
   Parametre(s) de sortie :
   Valeurs de retour normales :
     LCRZO_ERR_OK : ok
*/
int lcrzo_process_current_priority_set(lcrzo_int8 priority);

/*-------------------------------------------------------------*/
/*en Name : lcrzo_process_current_priority_get
   Description :
     Obtain the priority level of the current process.
   Input parameter(s) :
   Input/output parameter(s) :
   Output parameter(s) :
     *ppriority : priority
   Normal return values :
     LCRZO_ERR_OK : ok
*/
/*fr Nom : lcrzo_process_current_priority_get
   Description :
     Obtient le niveau de priorite du processus courant.
   Parametre(s) d'entree :
   Parametre(s) d'entree-sortie :
   Parametre(s) de sortie :
     *ppriority : priorite
   Valeurs de retour normales :
     LCRZO_ERR_OK : ok
*/
int lcrzo_process_current_priority_get(lcrzo_int8 *ppriority);


/*-------------------------------------------------------------*/
/*-------------------------------------------------------------*/
/*en Name : lcrzo_process_other_init
   Description :
     Create a new process, which will execute *pfunc and exit.
     Under Unix, value returned by pfunc is truncated to 8 
     bits : use lcrzo_process_other_init2 instead.
   Input parameter(s) :
     *pfunc : function executed by the new process :
                infos : set with infos
		infossize : set with infosize
		*pparentprocess : inform who is the father process
     infos : data to pass to the child process (infos is a void*
             because of Wcast-align on Sparc, which cause a sigbus)
     infossize : size of infos
     *pchidprocess : process created
   Input/output parameter(s) :
   Output parameter(s) :
   Normal return values :
     LCRZO_ERR_OK : ok
*/
/*fr Nom : lcrzo_process_other_init
   Description :
     Cree un nouveau processus qui execute *pfuns puis quitte.
     Sous Unix, la valeur retournee par pfunc est tronquee a 8
     bits : employer alors lcrzo_process_other_init2.
   Parametre(s) d'entree :
     *pfunc : fonction executee par le nouveau processus :
                infos : affecte avec infos
		infossize : affecte avec infossize
		*pparentprocess : informe qui est le processus pere
     infos : donnees a passer au processus fils (infos est un void*
             a cause de Wcast-align sur Sparc, qui cause un sigbus)
     infossize : taille de infos
     *pchidprocess : processus cree
   Parametre(s) d'entree-sortie :
   Parametre(s) de sortie :
   Valeurs de retour normales :
     LCRZO_ERR_OK : ok
*/
int lcrzo_process_other_init(int (*pfunc)(void *infos, 
					  lcrzo_int32 infossize, 
					  lcrzo_process *pparentprocess),
			     void *infos,
                             lcrzo_int32 infossize,
			     lcrzo_process *pchildprocess);

/*-------------------------------------------------------------*/
/*en Name : lcrzo_process_other_init2
   Description :
     Create a new process, which will execute *pfunc and exit.
     Under Unix, value returned by pfunc is truncated to 8 
     bits. So, functions punixreturn_int2uint8 and 
     punixreturn_uint82int can be used to compress integer and
     then expand them. You can for example use 
     lcrzo_process_int2uint8_std or create your own conversion
     function.
   Input parameter(s) :
     *pfunc : function executed by the new process :
                infos : set with infos
		infossize : set with infosize
		*pparentprocess : inform who is the father process
     infos : data which can be passed to the child process
     infossize : size of infos
     *punixreturn_int2uint8 : function used to convert the returned
                              value to 8 bits
     *punixreturn_uint82int : function used to convert an 8bitvalue
                              to an integer
     *pchidprocess : process created
   Input/output parameter(s) :
   Output parameter(s) :
   Normal return values :
     LCRZO_ERR_OK : ok
*/
/*fr Nom : lcrzo_process_other_init2
   Description :
     Cree un nouveau processus qui execute *pfuns puis quitte.
     Sous Unix, la valeur retournee par pfunc est tronquee a 8
     bits. Alors, les fonctions punixreturn_int2uint8 et 
     punixreturn_uint82int peuvent etre employees pour compresser
     un entier, puis l'etendre. Vous pouvez par exemple employer
     lcrzo_process_int2uint8_std ou creer votre propre fonction
     de conversion.
   Parametre(s) d'entree :
     *pfunc : fonction executee par le nouveau processus :
                infos : affecte avec infos
		infossize : affecte avec infossize
		*pparentprocess : informe qui est le processus pere
     infos : donnees a passer au processus fils
     infossize : taille de infos
     *punixreturn_int2uint8 : fonction employee pour compresser la
                              valeur retournee en 8 bits
     *punixreturn_uint82int : function employee pour convertir les
                              8 bits en entier
     *pchidprocess : processus cree
   Parametre(s) d'entree-sortie :
   Parametre(s) de sortie :
   Valeurs de retour normales :
     LCRZO_ERR_OK : ok
*/
int lcrzo_process_other_init2(int (*pfunc)(void *infos, 
					   lcrzo_int32 infossize, 
					   lcrzo_process *pparentprocess),
			      void *infos,
			      lcrzo_int32 infossize,
			      lcrzo_uint8 (*punixreturn_int2uint8)(int ret),
			      int (*punixreturn_uint82int)(lcrzo_uint8 ret),
			      lcrzo_process *pchildprocess);

/*-------------------------------------------------------------*/
/*en Name : lcrzo_process_other_exit
   Description :
     Terminate abruptly a process : use it only if you do not
     need to close things before ending.
   Input parameter(s) :
     *pprocess : process to terminate
   Input/output parameter(s) :
   Output parameter(s) :
   Normal return values :
     LCRZO_ERR_OK : ok
*/
/*fr Nom : lcrzo_process_other_exit
   Description :
     Termine brutalement un processus : a n'employer que si il
     n'y a rien a fermer avant de terminer.
   Parametre(s) d'entree :
     *pprocess : processus a terminer
   Parametre(s) d'entree-sortie :
   Parametre(s) de sortie :
   Valeurs de retour normales :
     LCRZO_ERR_OK : ok
*/
int lcrzo_process_other_exit(lcrzo_process *pprocess);

/*-------------------------------------------------------------*/
/*en Name : lcrzo_process_other_wait_end
   Description :
     Wait for the end of the process.
   Input parameter(s) :
     *pprocess : process to wait for
     *pmaxwaitingtime : maximum waiting time (can be a lcrzo_time,
                        LCRZO_WAIT_NODELAY or LCRZO_WAIT_INFINITE)
   Input/output parameter(s) :
   Output parameter(s) :
     *phasended : true if the process has ended
     *preturnvalue : value returned by the process
   Normal return values :
     LCRZO_ERR_OK : ok
     LCRZO_ERR_OKTEMPDATAEND : the function received nothing
                               before pmaxwaitingtime
*/
/*fr Nom : lcrzo_process_other_wait_end
   Description :
     Attend la fin d'un processus.
   Parametre(s) d'entree :
     *pprocess : processus a attendre
     *pmaxwaitingtime : temps maximum d'attente (peut etre un
                        lcrzo_time, LCRZO_WAIT_NODELAY ou
                        LCRZO_WAIT_INFINITE)
   Parametre(s) d'entree-sortie :
   Parametre(s) de sortie :
     *phasended : vrai si le processus a termine
     *preturnvalue : valeur retournee par le processus
   Valeurs de retour normales :
     LCRZO_ERR_OK : ok
     LCRZO_ERR_OKTEMPDATAEND : la fonction n'a pas recu de donnees
                               avant pmaxwaitingtime
*/
int lcrzo_process_other_wait_end(lcrzo_process *pprocess,
                                 lcrzo_time *pmaxwaitingtime,
                                 lcrzo_bool *phasended,
                                 int *preturnvalue);

/*-------------------------------------------------------------*/
/*en Name : lcrzo_process_close
   Description :
     Free memory allocated by a lcrzo_process.
     Note : this function does not teminate the processus.
   Input parameter(s) :
     *pprocess : process to free
   Input/output parameter(s) :
   Output parameter(s) :
   Normal return values :
     LCRZO_ERR_OK : ok
*/
/*fr Nom : lcrzo_process_close
   Description :
     Libere la memoire employee par un lcrzo_process.
     Note : cette fonction ne termine pas le processus.
   Parametre(s) d'entree :
     *pprocess : processus a liberer
   Parametre(s) d'entree-sortie :
   Parametre(s) de sortie :
   Valeurs de retour normales :
     LCRZO_ERR_OK : ok
*/
int lcrzo_process_close(lcrzo_process *pprocess);


/*-------------------------------------------------------------*/
/*-------------------------------------------------------------*/
/*en 
  Those functions have the same usage as previous ones, except :
   - they deal with several sub-processes
   - each sub-process is referred by its index
*/
/*fr
  Ces fonctions ont le meme emploi que les fonctions precedentes,
  excepte :
   - elles gerent plusieurs sous-processus
   - chaque sous-processus est reference par son index
*/
typedef struct
{ lcrzo_list waitlist;
  lcrzo_list processlist;
} lcrzo_multiprocess;
int lcrzo_multiprocess_init(lcrzo_multiprocess *pmultiprocess);
int lcrzo_multiprocess_close(lcrzo_multiprocess *pmultiprocess);

int lcrzo_multiprocess_process_init(lcrzo_multiprocess *pmultiprocess,
                                    lcrzo_int32 processindex,
                                    int (*pfunc)(void *infos, 
						 lcrzo_int32 infossize,
						lcrzo_process *pparentprocess),
			            void *infos,
                                    lcrzo_int32 infossize);
int lcrzo_multiprocess_process_init2(lcrzo_multiprocess *pmultiprocess,
				     lcrzo_int32 processindex,
				     int (*pfunc)(void *infos, 
						  lcrzo_int32 infossize,
						lcrzo_process *pparentprocess),
				     void *infos,
				     lcrzo_int32 infossize,
			      lcrzo_uint8 (*punixreturn_int2uint8)(int ret),
			      int (*punixreturn_uint82int)(lcrzo_uint8 ret));
int lcrzo_multiprocess_process_count(lcrzo_multiprocess *pmultiprocess,
                                     lcrzo_int32 *pnumberofprocesses);
int lcrzo_multiprocess_process_exit(lcrzo_multiprocess *pmultiprocess,
                                    lcrzo_int32 processindex);
int lcrzo_multiprocess_process_wait_end(lcrzo_multiprocess *pmultiprocess,
                                        lcrzo_time *pmaxwaitingtime,
                                        lcrzo_bool *paprocesshasended,
                                        lcrzo_int32 *pindexoftheendedprocess,
                                        int *preturnedvalue);

/*-------------------------------------------------------------*/
/*en Under Unix, the value returned by a process is truncated
   to 8 bits. Theses functions are used by lcrzo_process_other_init2.
     lcrzo_process_int2uint8_std : convert from 32 bits to 8 bits
     lcrzo_process_uint82int_std : convert from 8 bits to 32 bits
*/
/*fr Sous Unix, la valeur retournee par un processus est 
   tronquee a 8 bits. Ces fonctions sont utilisees par 
   lcrzo_process_other_init2.
     lcrzo_process_int2uint8_std : convertit de 32 bits a 8 bits
     lcrzo_process_uint82int_std : convertit de 8 bits a 32 bits
*/
lcrzo_uint8 lcrzo_process_int2uint8_std(int ret);
int lcrzo_process_uint82int_std(lcrzo_uint8 ret);

/*-------------------------------------------------------------*/
/*en Idem, but deals differently with truncation */
/*fr Idem, mais gere differemment la troncature */
lcrzo_uint8 lcrzo_process_int2uint8_socktcp(int ret);
int lcrzo_process_uint82int_socktcp(lcrzo_uint8 ret);


