aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2023-10-17 11:06:31 +0200
committerMartin Schanzenbach <schanzen@gnunet.org>2023-10-17 11:06:31 +0200
commite95236b3ed78cd597c15f34b89385295702b627f (patch)
tree732635788209701e98575c63c9df1ebc3772fb46
parent199338d4a07b4abec06b8dabfd71e580ddcc484b (diff)
downloadgnunet-e95236b3ed78cd597c15f34b89385295702b627f.tar.gz
gnunet-e95236b3ed78cd597c15f34b89385295702b627f.zip
meson: libgnunet main loop improvements
-rw-r--r--src/include/gnunet_service_lib.h2
-rw-r--r--src/util/service.c206
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 */
409void 409void
410GNUNET_SERVICE_main (void); 410GNUNET_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 */
2139struct ServiceHandleList 2143struct 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 */
2146static struct ServiceHandleList *hll_head = NULL; 2156static struct ServiceHandleList *hll_head = NULL;
2157
2158/* The service list */
2147static struct ServiceHandleList *hll_tail = NULL; 2159static struct ServiceHandleList *hll_tail = NULL;
2148 2160
2149int 2161int
@@ -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;
2220fail: 2189}
2221 if (-1 != sh->ready_confirm_fd) 2190
2191
2192static void
2193do_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
2236static void 2216static void
2237launch_registered_services (void *cls) 2217launch_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
2250void 2236void
2251GNUNET_SERVICE_main (void) 2237GNUNET_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);
2330shutdown:
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.