diff options
author | Martin Schanzenbach <schanzen@gnunet.org> | 2023-10-17 11:06:31 +0200 |
---|---|---|
committer | Martin Schanzenbach <schanzen@gnunet.org> | 2023-10-17 11:06:31 +0200 |
commit | e95236b3ed78cd597c15f34b89385295702b627f (patch) | |
tree | 732635788209701e98575c63c9df1ebc3772fb46 | |
parent | 199338d4a07b4abec06b8dabfd71e580ddcc484b (diff) | |
download | gnunet-e95236b3ed78cd597c15f34b89385295702b627f.tar.gz gnunet-e95236b3ed78cd597c15f34b89385295702b627f.zip |
meson: libgnunet main loop improvements
-rw-r--r-- | src/include/gnunet_service_lib.h | 2 | ||||
-rw-r--r-- | src/util/service.c | 206 |
2 files changed, 146 insertions, 62 deletions
diff --git a/src/include/gnunet_service_lib.h b/src/include/gnunet_service_lib.h index 49f9cd68b..0ad4fcc3c 100644 --- a/src/include/gnunet_service_lib.h +++ b/src/include/gnunet_service_lib.h | |||
@@ -407,7 +407,7 @@ GNUNET_SERVICE_register_ ( | |||
407 | * Must be called such that services are actually launched. | 407 | * Must be called such that services are actually launched. |
408 | */ | 408 | */ |
409 | void | 409 | void |
410 | GNUNET_SERVICE_main (void); | 410 | GNUNET_SERVICE_main (int argc, char *const *argv); |
411 | 411 | ||
412 | /** | 412 | /** |
413 | * Suspend accepting connections from the listen socket temporarily. | 413 | * Suspend accepting connections from the listen socket temporarily. |
diff --git a/src/util/service.c b/src/util/service.c index baa8a3378..7aeabf687 100644 --- a/src/util/service.c +++ b/src/util/service.c | |||
@@ -2136,14 +2136,26 @@ shutdown: | |||
2136 | return err ? GNUNET_SYSERR : sh.ret; | 2136 | return err ? GNUNET_SYSERR : sh.ret; |
2137 | } | 2137 | } |
2138 | 2138 | ||
2139 | |||
2140 | /* A list of service to be launched when GNUNET_SERVICE_main() | ||
2141 | * is called | ||
2142 | */ | ||
2139 | struct ServiceHandleList | 2143 | struct ServiceHandleList |
2140 | { | 2144 | { |
2145 | /* DLL */ | ||
2141 | struct ServiceHandleList *prev; | 2146 | struct ServiceHandleList *prev; |
2147 | |||
2148 | /* DLL */ | ||
2142 | struct ServiceHandleList *next; | 2149 | struct ServiceHandleList *next; |
2143 | 2150 | ||
2151 | /* Handle to the service to launch */ | ||
2144 | struct GNUNET_SERVICE_Handle *sh; | 2152 | struct GNUNET_SERVICE_Handle *sh; |
2145 | }; | 2153 | }; |
2154 | |||
2155 | /* The service list */ | ||
2146 | static struct ServiceHandleList *hll_head = NULL; | 2156 | static struct ServiceHandleList *hll_head = NULL; |
2157 | |||
2158 | /* The service list */ | ||
2147 | static struct ServiceHandleList *hll_tail = NULL; | 2159 | static struct ServiceHandleList *hll_tail = NULL; |
2148 | 2160 | ||
2149 | int | 2161 | int |
@@ -2156,27 +2168,11 @@ GNUNET_SERVICE_register_ (const char *service_name, | |||
2156 | const struct GNUNET_MQ_MessageHandler *handlers) | 2168 | const struct GNUNET_MQ_MessageHandler *handlers) |
2157 | { | 2169 | { |
2158 | struct ServiceHandleList *hle; | 2170 | struct ServiceHandleList *hle; |
2159 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
2160 | struct GNUNET_SERVICE_Handle *sh = GNUNET_new (struct GNUNET_SERVICE_Handle); | 2171 | struct GNUNET_SERVICE_Handle *sh = GNUNET_new (struct GNUNET_SERVICE_Handle); |
2161 | const char *xdg; | ||
2162 | char *cfg_filename; | ||
2163 | const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get (); | 2172 | const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get (); |
2164 | int err; | ||
2165 | 2173 | ||
2166 | err = 1; | ||
2167 | xdg = getenv ("XDG_CONFIG_HOME"); | ||
2168 | if (NULL != xdg) | ||
2169 | GNUNET_asprintf (&cfg_filename, | ||
2170 | "%s%s%s", | ||
2171 | xdg, | ||
2172 | DIR_SEPARATOR_STR, | ||
2173 | pd->config_file); | ||
2174 | else | ||
2175 | cfg_filename = GNUNET_strdup (pd->user_config_file); | ||
2176 | sh->ready_confirm_fd = -1; | 2174 | sh->ready_confirm_fd = -1; |
2177 | sh->options = options; | 2175 | sh->options = options; |
2178 | cfg = GNUNET_CONFIGURATION_create (); | ||
2179 | sh->cfg = cfg; | ||
2180 | sh->service_init_cb = service_init_cb; | 2176 | sh->service_init_cb = service_init_cb; |
2181 | sh->connect_cb = connect_cb; | 2177 | sh->connect_cb = connect_cb; |
2182 | sh->disconnect_cb = disconnect_cb; | 2178 | sh->disconnect_cb = disconnect_cb; |
@@ -2186,73 +2182,161 @@ GNUNET_SERVICE_register_ (const char *service_name, | |||
2186 | : GNUNET_MQ_copy_handlers2 (handlers, &return_agpl, NULL); | 2182 | : GNUNET_MQ_copy_handlers2 (handlers, &return_agpl, NULL); |
2187 | sh->service_name = service_name; | 2183 | sh->service_name = service_name; |
2188 | sh->ret = 0; | 2184 | sh->ret = 0; |
2189 | if (GNUNET_YES == GNUNET_DISK_file_test (cfg_filename)) | ||
2190 | { | ||
2191 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cfg_filename)) | ||
2192 | { | ||
2193 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2194 | _ ("Malformed configuration file `%s', exit ...\n"), | ||
2195 | cfg_filename); | ||
2196 | goto fail; | ||
2197 | } | ||
2198 | } | ||
2199 | else | ||
2200 | { | ||
2201 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL)) | ||
2202 | { | ||
2203 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2204 | _ ("Malformed configuration, exit ...\n")); | ||
2205 | goto fail; | ||
2206 | } | ||
2207 | } | ||
2208 | if (GNUNET_OK != setup_service (sh)) | ||
2209 | goto fail; | ||
2210 | if (GNUNET_OK != set_user_id (sh)) | ||
2211 | goto fail; | ||
2212 | GNUNET_RESOLVER_connect (sh->cfg); | ||
2213 | |||
2214 | /* actually run service */ | ||
2215 | err = 0; | ||
2216 | hle = GNUNET_new (struct ServiceHandleList); | 2185 | hle = GNUNET_new (struct ServiceHandleList); |
2217 | hle->sh = sh; | 2186 | hle->sh = sh; |
2218 | GNUNET_CONTAINER_DLL_insert (hll_head, hll_tail, hle); | 2187 | GNUNET_CONTAINER_DLL_insert (hll_head, hll_tail, hle); |
2219 | /* shutdown */ | 2188 | return GNUNET_OK; |
2220 | fail: | 2189 | } |
2221 | if (-1 != sh->ready_confirm_fd) | 2190 | |
2191 | |||
2192 | static void | ||
2193 | do_registered_services_shutdown (void *cls) | ||
2194 | { | ||
2195 | struct GNUNET_SERVICE_Handle *sh; | ||
2196 | struct ServiceHandleList *shl; | ||
2197 | |||
2198 | for (shl = hll_head; NULL != shl;) | ||
2222 | { | 2199 | { |
2223 | if (1 != write (sh->ready_confirm_fd, err ? "I" : "S", 1)) | 2200 | sh = shl->sh; |
2224 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "write"); | 2201 | GNUNET_CONTAINER_DLL_remove (hll_head, hll_tail, shl); |
2225 | GNUNET_break (0 == close (sh->ready_confirm_fd)); | 2202 | GNUNET_free (shl); |
2203 | if (-1 != sh->ready_confirm_fd) | ||
2204 | { | ||
2205 | if (1 != write (sh->ready_confirm_fd, "S", 1)) | ||
2206 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "write"); | ||
2207 | GNUNET_break (0 == close (sh->ready_confirm_fd)); | ||
2208 | } | ||
2209 | teardown_service (sh); | ||
2210 | GNUNET_free (sh->handlers); | ||
2211 | GNUNET_free (sh); | ||
2226 | } | 2212 | } |
2227 | teardown_service (sh); | ||
2228 | GNUNET_free (sh->handlers); | ||
2229 | GNUNET_SPEEDUP_stop_ (); | ||
2230 | GNUNET_CONFIGURATION_destroy (cfg); | ||
2231 | GNUNET_free (cfg_filename); | ||
2232 | GNUNET_free (sh); | ||
2233 | return err ? GNUNET_SYSERR : sh->ret; | ||
2234 | } | 2213 | } |
2235 | 2214 | ||
2215 | |||
2236 | static void | 2216 | static void |
2237 | launch_registered_services (void *cls) | 2217 | launch_registered_services (void *cls) |
2238 | { | 2218 | { |
2239 | (void) cls; | ||
2240 | struct ServiceHandleList *shl; | 2219 | struct ServiceHandleList *shl; |
2220 | struct GNUNET_CONFIGURATION_Handle *cfg = cls; | ||
2241 | 2221 | ||
2242 | for (shl = hll_head; NULL != shl; shl = shl->next) | 2222 | for (shl = hll_head; NULL != shl; shl = shl->next) |
2243 | { | 2223 | { |
2224 | shl->sh->cfg = cfg; | ||
2225 | if (GNUNET_OK != setup_service (shl->sh)) | ||
2226 | continue; | ||
2227 | if (GNUNET_OK != set_user_id (shl->sh)) | ||
2228 | continue; | ||
2229 | |||
2244 | GNUNET_SCHEDULER_add_now (&service_main, shl->sh); | 2230 | GNUNET_SCHEDULER_add_now (&service_main, shl->sh); |
2245 | } | 2231 | } |
2246 | 2232 | GNUNET_SCHEDULER_add_shutdown (&do_registered_services_shutdown, NULL); | |
2247 | // FIXME sometime we need to cleanup the shl. Shutdown task? | ||
2248 | } | 2233 | } |
2249 | 2234 | ||
2235 | |||
2250 | void | 2236 | void |
2251 | GNUNET_SERVICE_main (void) | 2237 | GNUNET_SERVICE_main (int argc, |
2238 | char *const *argv) | ||
2252 | { | 2239 | { |
2253 | GNUNET_SCHEDULER_run (&launch_registered_services, NULL); | 2240 | char *cfg_filename; |
2241 | char *opt_cfg_filename; | ||
2242 | char *logfile; | ||
2243 | char *loglev; | ||
2244 | const char *xdg; | ||
2245 | int do_daemonize; | ||
2246 | int ret; | ||
2247 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
2248 | const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get (); | ||
2249 | |||
2250 | struct GNUNET_GETOPT_CommandLineOption service_options[] = { | ||
2251 | GNUNET_GETOPT_option_cfgfile (&opt_cfg_filename), | ||
2252 | GNUNET_GETOPT_option_flag ('d', | ||
2253 | "daemonize", | ||
2254 | gettext_noop ( | ||
2255 | "do daemonize (detach from terminal)"), | ||
2256 | &do_daemonize), | ||
2257 | GNUNET_GETOPT_option_help (NULL), | ||
2258 | GNUNET_GETOPT_option_loglevel (&loglev), | ||
2259 | GNUNET_GETOPT_option_logfile (&logfile), | ||
2260 | GNUNET_GETOPT_option_version (pd->version), | ||
2261 | GNUNET_GETOPT_OPTION_END | ||
2262 | }; | ||
2263 | xdg = getenv ("XDG_CONFIG_HOME"); | ||
2264 | if (NULL != xdg) | ||
2265 | GNUNET_asprintf (&cfg_filename, | ||
2266 | "%s%s%s", | ||
2267 | xdg, | ||
2268 | DIR_SEPARATOR_STR, | ||
2269 | pd->config_file); | ||
2270 | else | ||
2271 | cfg_filename = GNUNET_strdup (pd->user_config_file); | ||
2272 | cfg = GNUNET_CONFIGURATION_create (); | ||
2273 | // FIXME we need to set this up for each service! | ||
2274 | ret = GNUNET_GETOPT_run ("libgnunet", | ||
2275 | service_options, | ||
2276 | argc, | ||
2277 | argv); | ||
2278 | if (GNUNET_SYSERR == ret) | ||
2279 | goto shutdown; | ||
2280 | if (GNUNET_NO == ret) | ||
2281 | { | ||
2282 | goto shutdown; | ||
2283 | } | ||
2284 | // FIXME we need to set this up for each service! | ||
2285 | if (GNUNET_OK != GNUNET_log_setup ("libgnunet", | ||
2286 | loglev, | ||
2287 | logfile)) | ||
2288 | { | ||
2289 | GNUNET_break (0); | ||
2290 | goto shutdown; | ||
2291 | } | ||
2292 | if (NULL != opt_cfg_filename) | ||
2293 | { | ||
2294 | if ((GNUNET_YES != GNUNET_DISK_file_test (opt_cfg_filename)) || | ||
2295 | (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, opt_cfg_filename))) | ||
2296 | { | ||
2297 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2298 | _ ("Malformed configuration file `%s', exit ...\n"), | ||
2299 | opt_cfg_filename); | ||
2300 | goto shutdown; | ||
2301 | } | ||
2302 | } | ||
2303 | else | ||
2304 | { | ||
2305 | if (GNUNET_YES == GNUNET_DISK_file_test (cfg_filename)) | ||
2306 | { | ||
2307 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cfg_filename)) | ||
2308 | { | ||
2309 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2310 | _ ("Malformed configuration file `%s', exit ...\n"), | ||
2311 | cfg_filename); | ||
2312 | GNUNET_free (cfg_filename); | ||
2313 | return; | ||
2314 | } | ||
2315 | } | ||
2316 | else | ||
2317 | { | ||
2318 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL)) | ||
2319 | { | ||
2320 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2321 | _ ("Malformed configuration, exit ...\n")); | ||
2322 | GNUNET_free (cfg_filename); | ||
2323 | return; | ||
2324 | } | ||
2325 | } | ||
2326 | } | ||
2327 | GNUNET_RESOLVER_connect (cfg); | ||
2328 | |||
2329 | GNUNET_SCHEDULER_run (&launch_registered_services, cfg); | ||
2330 | shutdown: | ||
2331 | GNUNET_SPEEDUP_stop_ (); | ||
2332 | GNUNET_CONFIGURATION_destroy (cfg); | ||
2333 | GNUNET_free (logfile); | ||
2334 | GNUNET_free (loglev); | ||
2335 | GNUNET_free (cfg_filename); | ||
2336 | GNUNET_free (opt_cfg_filename); | ||
2254 | } | 2337 | } |
2255 | 2338 | ||
2339 | |||
2256 | /** | 2340 | /** |
2257 | * Suspend accepting connections from the listen socket temporarily. | 2341 | * Suspend accepting connections from the listen socket temporarily. |
2258 | * Resume activity using #GNUNET_SERVICE_resume. | 2342 | * Resume activity using #GNUNET_SERVICE_resume. |