Commit 8ce82a6b authored by Lucas Russo's avatar Lucas Russo

src,include{dev_io}: add general operations structure handlers

This was based on the functions available on
dev_mngr (src/dev_mngr/dev_mngr_core.c and
include/dev_io_core.h)
parent 07dbbea5
......@@ -16,6 +16,30 @@ extern "C" {
#define SMIO_HKEY_LEN 8
#define NODES_MAX_LEN 20
/* Signal handler function pointer */
typedef void (*sig_handler_fp)(int sig, siginfo_t *siginfo, void *context);
/* Wait child handler function pointer */
typedef int (*wait_chld_handler_fp)(void);
/* Wait child with timeout handler function pointer */
typedef int (*wait_chld_timed_handler_fp)(int timeout);
/* Spawn child handler function pointer */
typedef int (*spawn_chld_handler_fp)(const char *program, char *const argv[]);
/* Node of sig_ops list */
typedef struct {
int signal; /* Signal identifier, e.g., SIGINT, SIGKILL, etc... */
sig_handler_fp devio_sig_h;
} devio_sig_handler_t;
typedef struct {
wait_chld_handler_fp devio_wait_chld; /* Called to wait a all child process */
wait_chld_timed_handler_fp devio_wait_chld_timed; /* Called to wait a all child process */
spawn_chld_handler_fp devio_spawn_chld; /* Called to spawn a new process to handle device */
/* List of devio_sig_handler_t */
zlistx_t *sig_ops;
} devio_ops_t;
typedef struct {
disp_table_func_fp thsafe_server_open; /* Open device */
disp_table_func_fp thsafe_server_release; /* Release device */
......@@ -68,6 +92,26 @@ devio_err_e devio_set_llio (devio_t *self, llio_t *llio);
/* Get LLIO instance from DEVIO */
llio_t *devio_get_llio (devio_t *self);
/* Register signals to Device Manager instance */
devio_err_e devio_set_sig_handler (devio_t *self, devio_sig_handler_t *sig_handler);
/* Register all signal handlers previously set */
devio_err_e devio_register_sig_handlers (devio_t *self);
/* Register function to wait a all child process */
devio_err_e devio_set_wait_clhd_handler (devio_t *self, wait_chld_handler_fp fp);
/* Register function to wait with timeout a all child process */
devio_err_e devio_set_wait_clhd_timed_handler (devio_t *self, wait_chld_timed_handler_fp fp);
/* Execute function to wait a all child process */
devio_err_e devio_wait_chld (devio_t *self);
/* Execute function to wait with timeout all child process */
devio_err_e devio_wait_chld_timed (devio_t *self, int timeout);
/* Register function to spawn a all child process */
devio_err_e devio_set_spawn_clhd_handler (devio_t *self, spawn_chld_handler_fp fp);
/* Execute function to spawn a all child process */
devio_err_e devio_spawn_chld (devio_t *self, const char *program, char *const argv[]);
/* Setting all operations at once */
devio_err_e devio_set_ops (devio_t *self, devio_ops_t *devio_ops);
/********* Low-level generic methods API *********/
/* Open device */
......
......@@ -32,6 +32,9 @@ enum _devio_err_e {
DEVIO_ERR_INV_SOCKET, /* Invalid socket reference */
DEVIO_ERR_MOD_LLIO, /* Error modifying LLIO instance */
DEVIO_ERR_CFG, /* Could not get property from config file */
DEVIO_ERR_SIGACTION, /* Could not register signal */
DEVIO_ERR_WAITCHLD, /* Wait child routine error */
DEVIO_ERR_SPAWNCHLD, /* Spawn child routine error */
DEVIO_ERR_END /* End of enum marker */
};
......
......@@ -269,7 +269,9 @@ int main (int argc, char *argv[])
DBE_DEBUG (DBG_DEV_IO | DBG_LVL_INFO, "[ebpm] Spawing DEVIO Config\n");
char *argv_exec [] = {DEVIO_CFG_NAME, "-n", devio_type_str,"-t", dev_type,
"-i", dev_id_str, "-e", dev_entry, "-b", broker_endp, NULL};
/* Spawn Config DEVIO */
/* Spawn Config DEVIO. */
/* We can't use devio_spawn_chld as DEVIO does not exist
* just yet. So, we stick with "hutils" implementation */
child_devio_cfg_pid = hutils_spawn_chld (DEVIO_CFG_NAME, argv_exec);
if (child_devio_cfg_pid < 0) {
......@@ -328,6 +330,8 @@ int main (int argc, char *argv[])
kill (child_devio_cfg_pid, DEVIO_KILL_CFG_SIGNAL);
}
/* Wait child up to 5 seconds before giving up waiting */
/* We can't use devio_spawn_chld as DEVIO does not exist
* just yet. So, we stick with "hutils" implementation */
hutils_wait_chld_timed (5000);
}
/* Destroy libclient */
......@@ -452,7 +456,7 @@ err_devio_hints_alloc:
free (devio_log_filename);
err_devio_log_filename_alloc:
/* wait child, if any */
hutils_wait_chld ();
devio_wait_chld (devio);
devio_destroy (&devio);
err_card_slot:
#if defined (__BOARD_AFCV3__) && (__WITH_APP_CFG__)
......@@ -571,7 +575,7 @@ static devio_err_e _spawn_rffe_devios (devio_t *devio, uint32_t dev_id,
ETH_DEV_STR, "-i", dev_id_c, "-e", cfg_item->bind, "-s", smio_inst_id_c,
"-b", broker_endp, "-l", log_prefix, NULL};
/* Spawn Config DEVIO */
int child_devio_cfg_pid = hutils_spawn_chld (DEVIO_NAME, argv_exec);
int child_devio_cfg_pid = devio_spawn_chld (devio, DEVIO_NAME, argv_exec);
if (child_devio_cfg_pid < 0) {
DBE_DEBUG (DBG_DEV_IO | DBG_LVL_FATAL, "[ebpm] Could not create "
......@@ -668,7 +672,7 @@ static devio_err_e _spawn_epics_iocs (devio_t *devio, uint32_t dev_id,
"^D^C", telnet_port_c, EPICS_BPM_RUN_SCRIPT_NAME, broker_endp, bpm_id_c,
NULL};
/* Spawn Config DEVIO */
int child_devio_cfg_pid = hutils_spawn_chld (EPICS_PROCSERV_NAME, argv_exec);
int child_devio_cfg_pid = devio_spawn_chld (devio, EPICS_PROCSERV_NAME, argv_exec);
if (child_devio_cfg_pid < 0) {
DBE_DEBUG (DBG_DEV_IO | DBG_LVL_FATAL, "[ebpm] Could not create "
......
......@@ -54,6 +54,8 @@ struct _devio_t {
char *endpoint_broker; /* Broker location to connect to */
int verbose; /* Print activity to stdout */
/* General management operations */
devio_ops_t *ops;
/* ll_io instance for Low-Level operations*/
llio_t *llio;
/* Server part of the llio operations. This is the bridge between the
......@@ -88,6 +90,12 @@ static devio_err_e _devio_destroy_actor (devio_t *self, zactor_t **actor);
static devio_err_e _devio_destroy_smio (devio_t *self, zhashx_t *smio_h, const char *smio_key);
static devio_err_e _devio_destroy_smio_all (devio_t *self, zhashx_t *smio_h);
/* General operations set handlers */
static devio_err_e _devio_set_wait_clhd_handler (devio_t *self, wait_chld_handler_fp fp);
static devio_err_e _devio_set_wait_clhd_timed_handler (devio_t *self, wait_chld_timed_handler_fp fp);
static devio_err_e _devio_set_spawn_clhd_handler (devio_t *self, spawn_chld_handler_fp fp);
static devio_err_e _devio_register_sig_handlers (devio_t *self);
/* Creates a new instance of Device Information */
devio_t * devio_new (char *name, uint32_t id, char *endpoint_dev,
llio_type_e type, char *endpoint_broker, int verbose,
......@@ -154,6 +162,20 @@ devio_t * devio_new (char *name, uint32_t id, char *endpoint_dev,
ASSERT_ALLOC(self->endpoint_broker, err_endp_broker_alloc);
self->verbose = verbose;
/* Create General operations structures */
self->ops = (devio_ops_t *) zmalloc (sizeof *self->ops);
ASSERT_ALLOC(self->ops, err_ops_alloc);
self->ops->sig_ops = zlistx_new ();
ASSERT_ALLOC(self->ops->sig_ops, err_list_alloc);
/* Setup default general operations */
_devio_set_wait_clhd_handler (self, &hutils_wait_chld);
_devio_set_wait_clhd_timed_handler (self, &hutils_wait_chld_timed);
_devio_set_spawn_clhd_handler (self, &hutils_spawn_chld);
devio_err_e derr = _devio_register_sig_handlers (self);
ASSERT_TEST(derr==DEVIO_SUCCESS, "Error setting up signal handlers", err_sig_handlers);
/* Concatenate recv'ed name with a llio identifier */
char *llio_name = zmalloc (sizeof (char)*(strlen(name)+strlen(LLIO_STR)+1));
ASSERT_ALLOC(llio_name, err_llio_name_alloc);
......@@ -213,6 +235,12 @@ err_llio_open:
err_llio_alloc:
free (llio_name);
err_llio_name_alloc:
/* Nothing to undo */
err_sig_handlers:
zlistx_destroy (&self->ops->sig_ops);
err_list_alloc:
free (self->ops);
err_ops_alloc:
free (self->endpoint_broker);
err_endp_broker_alloc:
free (self->name);
......@@ -276,6 +304,14 @@ devio_err_e devio_destroy (devio_t **self_p)
llio_destroy (&self->llio);
DBE_DEBUG (DBG_DEV_IO | DBG_LVL_INFO,
"[dev_io_core:destroy] LLIO destroyed\n");
DBE_DEBUG (DBG_DEV_IO | DBG_LVL_INFO,
"[dev_io_core:destroy] Destroying general operation handlers\n");
zlistx_destroy (&self->ops->sig_ops);
free (self->ops);
DBE_DEBUG (DBG_DEV_IO | DBG_LVL_INFO,
"[dev_io_core:destroy] General operation handlers destroyed\n");
free (self->endpoint_broker);
free (self->name);
DBE_DEBUG (DBG_DEV_IO | DBG_LVL_INFO,
......@@ -704,6 +740,132 @@ llio_t *devio_get_llio (devio_t *self)
return self->llio;
}
devio_err_e devio_set_sig_handler (devio_t *self, devio_sig_handler_t *sig_handler)
{
assert (self);
void *handle = zlistx_add_end (self->ops->sig_ops, sig_handler);
return (handle == NULL) ? DEVIO_ERR_ALLOC : DEVIO_SUCCESS;
}
static devio_err_e _devio_register_sig_handlers (devio_t *self)
{
assert (self);
devio_sig_handler_t *sig_handler =
(devio_sig_handler_t *) zlistx_first (self->ops->sig_ops);
/* Register all signal handlers in list*/
while (sig_handler) {
struct sigaction act;
memset (&act, 0, sizeof(act));
act.sa_sigaction = sig_handler->devio_sig_h;
act.sa_flags = SA_SIGINFO;
int err = sigaction (sig_handler->signal, &act, NULL);
CHECK_ERR(err, DEVIO_ERR_SIGACTION);
DBE_DEBUG (DBG_DEV_MNGR | DBG_LVL_INFO, "[dev_mngr_core] registered signal %d\n",
sig_handler->signal);
sig_handler = (devio_sig_handler_t *)
zlistx_next (self->ops->sig_ops);
}
return DEVIO_SUCCESS;
}
devio_err_e devio_register_sig_handlers (devio_t *self)
{
return _devio_register_sig_handlers (self);
}
/* Declare wrapper for all DEVIO functions API */
#define DEVIO_FUNC_WRAPPER(func_name, ops_err, ...) \
{ \
assert (self); \
CHECK_ERR(((self->ops->func_name == NULL) ? -1 : 0),\
DEVIO_ERR_FUNC_NOT_IMPL); \
int err = self->ops->func_name (__VA_ARGS__); \
CHECK_ERR (err, ops_err); \
return DEVIO_SUCCESS; \
}
static devio_err_e _devio_set_wait_clhd_handler (devio_t *self, wait_chld_handler_fp fp)
{
assert (self);
self->ops->devio_wait_chld = fp;
return DEVIO_SUCCESS;
}
devio_err_e devio_set_wait_clhd_handler (devio_t *self, wait_chld_handler_fp fp)
{
return _devio_set_wait_clhd_handler (self, fp);
}
static devio_err_e _devio_set_wait_clhd_timed_handler (devio_t *self, wait_chld_timed_handler_fp fp)
{
assert (self);
self->ops->devio_wait_chld_timed = fp;
return DEVIO_SUCCESS;
}
devio_err_e devio_set_wait_clhd_timed_handler (devio_t *self, wait_chld_timed_handler_fp fp)
{
return _devio_set_wait_clhd_timed_handler (self, fp);
}
static devio_err_e _devio_wait_chld (devio_t *self)
DEVIO_FUNC_WRAPPER(devio_wait_chld, DEVIO_ERR_WAITCHLD)
devio_err_e devio_wait_chld (devio_t *self)
{
return _devio_wait_chld (self);
}
static devio_err_e _devio_wait_chld_timed (devio_t *self, int timeout)
DEVIO_FUNC_WRAPPER(devio_wait_chld_timed, DEVIO_ERR_WAITCHLD, timeout)
devio_err_e devio_wait_chld_timed (devio_t *self, int timeout)
{
return _devio_wait_chld_timed (self, timeout);
}
static devio_err_e _devio_set_spawn_clhd_handler (devio_t *self, spawn_chld_handler_fp fp)
{
assert (self);
self->ops->devio_spawn_chld = fp;
return DEVIO_SUCCESS;
}
devio_err_e devio_set_spawn_clhd_handler (devio_t *self, spawn_chld_handler_fp fp)
{
return _devio_set_spawn_clhd_handler (self, fp);
}
static devio_err_e _devio_spawn_chld (devio_t *self, const char *program,
char *const argv[])
DEVIO_FUNC_WRAPPER(devio_spawn_chld, DEVIO_ERR_SPAWNCHLD, program, argv)
devio_err_e devio_spawn_chld (devio_t *self, const char *program,
char *const argv[])
{
return _devio_spawn_chld (self, program, argv);
}
devio_err_e devio_set_ops (devio_t *self, devio_ops_t *devio_ops)
{
assert (self);
assert (devio_ops);
self->ops = devio_ops;
return DEVIO_SUCCESS;
}
/************************************************************/
/***************** Dispatch table callbacks *****************/
/************************************************************/
......
......@@ -27,6 +27,9 @@ static const char *devio_err [DEVIO_ERR_END] =
[DEVIO_ERR_SMIO_DESTROY] = "Could not destroy sm_io instance",
[DEVIO_ERR_INV_SOCKET] = "Invalid socket reference",
[DEVIO_ERR_MOD_LLIO] = "Error modifying LLIO instance",
[DEVIO_ERR_SIGACTION] = "Signal registration error",
[DEVIO_ERR_WAITCHLD] = "Could not complete wait child routine",
[DEVIO_ERR_SPAWNCHLD] = "Could not complete spawn child routine",
[DEVIO_ERR_CFG] = "Could not get property from config file"
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment