Proc code - Solutions - TIMEOUT |
![]() |
Uniface permite, en algunos entornos, el parámetro $TIMEOUT en el fichero asn para hacer que se dispare una interrupción asíncrona (trigger ASYNC). Esta funcionalidad no es posible en sistemas Unix, pero utilizando la utilidad pidfmess suministrada por Uniface puede simularse tal y como aquí se explica. Nota. El comando pidfmess envía un mensaje a un proceso (identificado por su PID). Su formato es : pidfmess PID_de_la_aplicación msg, msg, msg.... La interrupción asíncrona. Al dispararse este trigger se ha de comprobar el tipo de interrupción que se la ha provocado consultando el valor de la variable $result que, en caso de tratarse de un timeout , contendrá el literal "timeout" . La implementación.Timeout para entornos Unix
3GL | - Se han de crear unos determinados procedimientos que permiten la recepción de mensajes a nuestra aplicación. |
Start Up Shell | - En el trigger execute se ha de habilitar (y deshabilitar) la funcionalidades anteriores y poner en marcha un shell script que envía la interrupción tras una espera de los segundos indicados |
- En el trigger asíncrono se ha de reconocer que se ha producido la interrupción, ejecutar el proceso que nos interese y a continuación volver a poner en marcha el script que enviará la siguiente interrupción. | |
Shell Script | - Recibe como parámetros el número de PID del proceso al que hay que enviarle el mensaje (el de nuestra aplicación) y el número de segundos a esperar. |
Fichero ASN | - Se crea el "logical" TIMEOUT que permite configurar el tiempo de timeout (supliendo en entornos Unix el parámetro $TIMEOUT) |
El código.
3GL
El código siguiente corresponde al fichero mylib.c que contiene tres procedimientos: AGET_PID para obtener el PID de la aplicación, AMSG_INIT para habilitar la recepción de mensajes y AMSG_STOP para finalizarlas.
Para obtener el fichero mylib.o se ha de compilar el fichero mylib.c de la siguiente forma:
cc -c mylib.c
/* Fichero mylib.c */
#include <stdlib.h>
/*Retorna : $1 con el PID del proceso*/
AGET_PID()
{
UPUTREG(1,getpid()); /* set $1 to process ID (numeric value) */
}
/* Preparar un proceso para recibir mensajes */
AMSG_INIT()
{
int result;
result = UASYNC(AMSG);
return( result == 0 ? 1 : result);
}
/* Finaliza la recepción de mensajes por un proceso*/
AMSG_STOP()
{
int result;
result = UNOASYNC();
return( result == 0 ? 1 : result);
}
/* Fin del fichero mylib.c */
Start-Up Shell
Añadir el fichero mylib.o en el apartado 3GL Modules & Libraries de la definición del StartUp Shell.
Se supone que el shell script (timeout) es accesible ($PATH)...
<TRIGGER EXECUTE>
variables
numeric sleep
endvariables
if ($oprsys = "U")
if ($logical("TIMEOUT") != "")
perform "AMSG_INIT" ; Habilitar mensajes
perform "AGET_PID" ; Obtener el PID
$$PID = $1 ; Guardamos el PID en una variable global
sleep = $logical("TIMEOUT") ; Obtenemos el timeout
spawn "timeout %%$$PID %%sleep &" ; Script en background
endif
endif
; Aquí comienza nuestra aplicación
activate "xxx".exec()
; Desactivar mensajes
if (($oprsys = "U") & ($logical("TIMEOUT") != ""))
perform "AMSG_STOP"
endif
<TRIGGER ASYNC>
variables
string mensaje
numeric sleep
endvariables
lowercase $result, mensaje
selectcase mensaje ; Comprobamos el tipo de interrupción recibido
case "timeout"
activate "proceso".exec()
if ($oprsys = "U") ; Sólo para Unix
sleep = $logical("TIMEOUT")
spawn "timeout %%$$PID %%sleep &" ; Siguiente interrupción
endif
case "message"
activate "loquesea".exec()
elsecase
activate "otro".exec()
endselectcase
El Shell script