You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
libsxmp/include/ydaemon/ydaemon.h

368 lines
9.2 KiB
C

/*
* Yet another daemon library especially designed to be used
* with libsxmp based daemons.
*
* (c) Alexander Vdolainen 2016 <avdolainen@zoho.com>
*
* libsxmp is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libsxmp is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
*
*/
#ifndef __YDAEMON_YDAEMON_H__
#define __YDAEMON_YDAEMON_H__
#include <stdint.h>
#include <time.h>
#include <sys/types.h>
#include <pthread.h>
#include <tdata/usrtc.h>
#include <tdata/idx_allocator.h>
#include <sexpr/sexp.h>
/* some syntax */
/**
* --values (variables)
*/
#define VAR_CREATE_GROUP "create-var-group"
#define VAR_SET "var-set"
/**
* --modules
* (%MODULE_ADD_SX '<name> <type>) -- add a module to the list of available modules
* (%MODULE_SET_SX '<name> (:%MODULE_PREFIX|%MODULE_PATHNAME|%MODULE_CNFPATH *<value>))
* *value might be the following:
* a. in case of double or single quote - will be taken as is
* b. without quotes will be interpreted as variable (must be defined before this expression)
*/
#define MODULE_ADD_SX "module-add"
#define MODULE_SET_SX "module-set" /** { */
/* module config values for _SET_SX */
#define MODULE_PREFIX "prefix"
#define MODULE_PATHNAME "pathname"
#define MODULE_CNFPATH "config-path"
/** } */
#define MODULE_LOAD_SX "module-load"
#define MODULE_RUN_SX "module-run"
/* internal functions */
#define SCMOBJECT "object"
/* functions for the logs */
#define YDOPENLOGS "yd-open-logfile"
/* limits */
#define MAX_SCM_FUNCTIONS 16384
#define MAX_SERVICES 8192
#define MAX_MODULES 4096
enum {
SCINT = 0,
SCCSTR,
SCOBJECTPTR,
SCUNDEFINED,
};
typedef struct __scm_ret {
uint8_t serr;
uint8_t type;
uint32_t len;
union {
void *ret;
struct {
int32_t ec;
uint32_t ru32;
};
};
} scret_t;
#define RETURN_SRET_SERR(r, e) (r).serr = e; return r
#define RETURN_SRET_IRES(r, e) (r).serr = 0; (r).type = SCINT; (r).ec = e; \
return r
#define RETURN_SRET_ORES(r, e) (r).serr = 0; (r).type = SCOBJECTPTR; (r).ret = (e); \
return r
struct __ydaemon_context_type;
/**
* @brief Type used to describe scm function
*
* It contains name i.e. keyword, pointer to the
* function itself and optional pointer to the
* implementation specific data. It packs to usrtc
* search structure.
*/
typedef struct __scm_func {
char *name;
scret_t (*call)(struct __ydaemon_context_type *, sexp_t *, void *);
void *priv;
usrtc_node_t node;
} scm_function_t;
/**
* @brief Type used to describe a tree of scm functions
*
* It contains a search structure with packed
* scm_function_t set and also contain special
* private pointer that might be optionally used
* by implementation.
*/
typedef struct __scm_func_tree {
usrtc_t functions;
void *priv;
} scm_function_tree_t;
/**
* @brief Values types
*
* Describes the type of value
* @see zdc_conf_val_t
*/
typedef enum {
STRING = 0,
INT,
UINT,
LONG,
ULONG,
BLOB,
SEXPR,
CUSTOM,
} ydc_val_type_t;
/**
* @brief configuration event
*
* Type used to describe events occured with values
*/
typedef enum {
YC_EVENT_ADD,
YC_EVENT_MODIFY,
YC_EVENT_DESTROY,
YC_EVENT_ATTACH,
} ydc_event_t;
/**
* @brief Type used to fit all required parameters
*
* It contain mode, system settings and a lot of other
* config defined parameters.
*/
typedef struct __ym_conf {
/* parameters groups */
usrtc_t p_groups; /**< Parameters groups */
/* functions tree */
void *init_funcs;
/* locking */
pthread_rwlock_t grp_lock; /**< Locking for groups */
pthread_mutex_t conf_lock; /**< Locking for state change, function ops, system io */
} ydc_conf_t;
/**
* @brief Type of the parameters group
*
* Store values.
*/
typedef struct __ym_pgroup {
usrtc_t values;
usrtc_node_t unode;
char *name;
pthread_rwlock_t val_lock;
} ydc_pgroup_t;
/**
* @brief Type used to describe value
*
* Used to store value.
*/
typedef struct __ym_conf_value {
usrtc_node_t unode;
ydc_val_type_t type;
int len;
char *name;
void *value;
void (*on_eventv)(struct __ym_conf_value *,
struct __ym_conf_value *,
ydc_conf_t *, ydc_event_t);
void *priv;
} ydc_conf_val_t;
typedef struct __ydaemon_log_type {
FILE *logstream;
int verbose_level;
int se;
} yd_log_t;
typedef struct __ydaemon_context_type {
usrtc_t *services;
usrtc_t *modules;
scm_function_tree_t *func; /** < functions for configuration and processing */
ydc_conf_t *values; /** < values stored by the groups */
yd_log_t *logcontext;
int flags;
pthread_rwlock_t modlock;
pthread_mutex_t looplock;
int daemon;
} yd_context_t;
#define yd_mod_ctx_wrlock(n) pthread_rwlock_wrlock(&(n)->modlock)
#define yd_mod_ctx_rdlock(n) pthread_rwlock_rdlock(&(n)->modlock)
#define yd_mod_ctx_unlock(n) pthread_rwlock_unlock(&(n)->modlock)
typedef enum {
YD_SERVICE_MUX = 0,
YD_SXMP_MOD,
YD_DATASTORE_MOD,
YD_OTHER,
} yd_mod_type_t;
typedef struct __ydaemon_module {
char *name;
char *pathname;
char *cnfname;
char *prefix;
void *dlhandle;
void *(*getobject)(void *, const char *);
int (*shutdown)(yd_context_t *);
int (*preinit)(yd_context_t *);
int (*init)(yd_context_t *);
int (*run)(yd_context_t *);
yd_mod_type_t type;
int flags;
usrtc_node_t node;
} yd_mod_t;
/* functions defines for modules */
#define def_shutdown(PREFIX) int PREFIX ## _shutdown(yd_context_t *ctx)
#define def_preinit(PREFIX) int PREFIX ## _preinit(yd_context_t *ctx)
#define def_init(PREFIX) int PREFIX ## _init(yd_context_t *ctx)
#define def_run(PREFIX) int PREFIX ## _run(yd_context_t *ctx)
#define def_getobject(PREFIX) void* PREFIX ## _getobject(void *priv, const char *oname)
/* function arguments macros */
#define def_ctx ctx
#define defpriv priv
#define defoname oname
#define yd_mod_set_prefix(n, p) (n)->prefix = (p)
#define yd_mod_set_pathname(n, p) (n)->pathname = (p)
#define yd_mod_set_cfgpath(n, p) (n)->cnfname = (p)
#define yd_mod_preinit(n) \
{ memset((n), 0, sizeof(yd_mod_t)); usrtc_node_init((n)->node, (n)); }
int yd_mod_init(yd_context_t *, yd_mod_t *);
int yd_mod_get(yd_context_t *, const char *, yd_mod_t **);
int yd_mod_load(yd_context_t *, yd_mod_t *);
int yd_mod_run(yd_context_t *, yd_mod_t *);
int yd_mod_shutdown(yd_context_t *, yd_mod_t *);
void *yd_mod_getobject(yd_context_t *, yd_mod_t *, void *, const char *);
void *yd_mod_getsym(yd_context_t *, yd_mod_t *, const char *);
typedef struct __ydaemon_service {
char *name; /* name of the service */
void *ops; /* the subject to think about ... */
void *connection; /* as backends private data */
void *conf; /* special configuration */
usrtc_node_t node;
} yd_service_t;
#define yd_ctx_values(c) (c)->values
int yd_init_ctx(yd_context_t *);
int yd_eval_ctx(yd_context_t *, const char *);
scret_t yd_eval_sexp(yd_context_t *, sexp_t *);
int yd_mainloop(yd_context_t *);
void yd_mainloop_exit(yd_context_t *);
int yd_set_daemonize(yd_context_t *, int);
/* modules related functions */
int yd_mod_add(yd_context_t *, const char *, yd_mod_type_t);
/* internal functions API */
void scm_func_tree_free(scm_function_tree_t *pt);
int scm_func_tree_init(scm_function_tree_t **pt, void *priv);
int scm_func_tree_insert(yd_context_t *zdx, const char *name,
scret_t (*call)(yd_context_t *, sexp_t *, void *),
void *priv);
int scm_func_tree_insert_t(yd_context_t *zdx, scm_function_t *f);
scret_t scm_func_tree_call(yd_context_t *zdx, void *cnf, sexp_t *sx,
char *name);
int scm_func_tree_delete(yd_context_t *zdx, char *name);
/* variables related functions */
int ydc_conf_init(ydc_conf_t *);
int ydc_conf_create_pgroup(ydc_conf_t *, char *);
int ydc_conf_get_val(ydc_conf_t *, const char *, ydc_conf_val_t **);
int ydc_conf_add_val_p(ydc_conf_t *, const char *, int);
/* some internal stuff */
#define UNIT_TESTS 1
#ifdef UNIT_TESTS
#define blub printf("%d at %s\n", __LINE__, __FUNCTION__)
#endif
/* logging */
enum {
YL_DEBUG = 0,
YL_INFO,
YL_WARN,
YL_ERROR,
};
void ydlog(yd_context_t *ctx, int olvl, const char *fmt, ...);
void yddaemon(yd_context_t *ctx);
/* object storage */
#define MAX_OBJECTS 65535
typedef struct __ostore_type {
usrtc_t objects;
pthread_rwlock_t rwlock;
} obj_store_t;
typedef struct __ostore_node_type {
char *name;
void *objdata;
usrtc_node_t node;
} obj_store_node_t;
int obj_store_init(obj_store_t *);
int obj_store_set(obj_store_t *, const char *, void *);
int obj_store_get(obj_store_t *, const char *, void **);
int obj_store_remove(obj_store_t *, const char *);
#endif /* __YDAEMON_YDAEMON_H__ */