diff options
| author | Tristan Riehs <tristan.riehs@bordeaux-inp.fr> | 2024-06-22 16:19:05 +0900 | 
|---|---|---|
| committer | Tristan Riehs <tristan.riehs@bordeaux-inp.fr> | 2024-06-22 16:19:05 +0900 | 
| commit | 7119092665e1b771b04b305813be81e9892dfc1b (patch) | |
| tree | 3856526163d627c16e83d86873337aea03199b16 | |
| parent | 14e0d1887808a3d8233dd14877bce7da2fe8ca12 (diff) | |
Improve disp API and implement dynamic reload
| -rw-r--r-- | src/disp.c | 77 | ||||
| -rw-r--r-- | src/disp.h | 20 | 
2 files changed, 75 insertions, 22 deletions
| @@ -25,10 +25,6 @@  #include "disp.h" -/* Reserved return values for the read_input function. */ -#define DISP_ERR INT_MAX -#define DISP_RELOAD (INT_MAX - 1) -  #define dlsym_and_check(dest, name)				\  	dest->name = dlsym(dest->dl_handle, #name);		\  	if ((!dest->name) || (dest->name == dest->dl_handle)) {	\ @@ -36,42 +32,85 @@  		fprintf(stderr, "calculer: %s\n", msg);		\  		dlclose(dest->dl_handle);			\  		free(dest);					\ -		return NULL;					\ +		return -1;					\  	} -struct disp * -get_disp(char *disp_name) +static int +load_symbols(struct disp *disp)  { -#ifndef NDEBUG -	/* displays are shared libraries */ -	char so_path[64] = {0}; -	strcpy(so_path, "./src/.libs/"); -	strcat(so_path, disp_name); -	strcat(so_path, ".so.0.0.0"); -	void *handle = dlopen(so_path, RTLD_LAZY); +	void *handle = dlopen(disp->so_path, RTLD_LAZY);  	if (!handle)  	{ -		char *msg = dlerror(); -		fprintf(stderr, "calculer: %s\n", msg); +		fprintf(stderr, "calculer: %s\n", dlerror());  		exit(1);  	} -	printf("INFO: successfully loaded symbols from \"%s\"\n", so_path); +#ifndef NDEBUG +	printf("INFO: successfully loaded symbols from \"%s\"\n", disp->so_path); +#endif -	struct disp *disp = malloc(sizeof(*disp));  	disp->dl_handle = handle;  	dlsym_and_check(disp, init);  	dlsym_and_check(disp, display_calc);  	dlsym_and_check(disp, read_input);  	dlsym_and_check(disp, display_res);  	dlsym_and_check(disp, destroy); +#ifndef NDEBUG  	dlsym_and_check(disp, pre_reload);  	dlsym_and_check(disp, post_reload); +#endif +	return 0; +} -	return disp; +struct disp * +get_disp(char *disp_name) +{ +#ifndef NDEBUG +	/* displays are shared libraries */ +	char so_path[64] = {0}; +	strcpy(so_path, "./src/.libs/"); +	strcat(so_path, disp_name); +	strcat(so_path, ".so.0.0.0"); +	struct disp *disp = malloc(sizeof(*disp)); +	disp->so_path = strdup(so_path); + +	return load_symbols(disp) == 0 ? disp : NULL;  #else  #  error "not available yet"  #endif  	return NULL;  } + +void +destroy_disp(struct disp *disp) +{ +	disp->destroy(); +	dlclose(disp->dl_handle); +	free(disp->so_path); +	free(disp); +} + +#ifndef NDEBUG +void +disp_reload(struct disp *disp) +{ +	int status; +	printf("INFO: saving state\n"); +	void *state = disp->pre_reload(); +	printf("INFO: closing shared library\n"); +	dlclose(disp->dl_handle); +	printf("INFO: reloading symbols\n"); +	status = load_symbols(disp); + +	if (status == -1) +	{ +		printf("calculer: %s\n", dlerror()); +		exit(1); +	} + +	printf("INFO: loading state\n"); +	disp->post_reload(state); +	printf("INFO: reloading done\n"); +} +#endif @@ -18,11 +18,19 @@  #define DISP_H  #include <stdbool.h> +#include <limits.h>  /* Available display types. */  #define DISP_CLI "cli"  #define DISP_RAY "ray" +/* Reserved return values for the read_input function. */ +#ifndef NDEBUG +#  define DISP_RELOAD INT_MAX +#endif +#define DISP_QUIT (INT_MAX - 1) +#define DISP_ERR (INT_MAX - 2) +  struct disp {  	void *dl_handle;  	void (*init)(void); @@ -30,13 +38,19 @@ struct disp {  	int  (*read_input)(void);  	void (*display_res)(bool, int);  	void (*destroy)(void); +#ifndef NDEBUG +	char *so_path;  	void *(*pre_reload)(void);  	void (*post_reload)(void *); +#endif  };  /* Get a display handler for the given display type. */ -struct disp *get_disp(char *disp_name); +struct disp *get_disp(char *); +void destroy_disp(struct disp *); -void destroy_disp(void); +#ifndef NDEBUG +void disp_reload(struct disp *); +#endif	/* NDEBUG */ -#endif +#endif	/* DISP_H */ | 
