INFO("All threads have exited, sending SIGTERM to remaining children");
kill(-radius_pid, SIGTERM);
}
+
+ /*
+ * Remove the semaphore, allowing other processes
+ * to start. We do this before the cleanup label
+ * as the parent process MUST NOT call this
+ * function as it exits, otherwise the semaphore
+ * is removed and there's no exclusivity.
+ */
+ main_config_exclusive_proc_done(main_config);
+
cleanup:
/*
* This may not have been done earlier if we're
* running the process under something like systemd and running it under
* debug mode.
*/
-static int _exclusive_proc_close_sem(unsigned int *sem_id_p)
+void main_config_exclusive_proc_done(main_config_t *config)
{
- fr_sem_close(*sem_id_p, NULL);
- return 0;
+ fr_sem_close(config->multi_proc_sem_id, NULL);
}
/** Check to see if we're the only process using this configuration file
ret = fr_sem_wait(sem_id, path, true, true);
switch (ret) {
case 0: /* we have the semaphore */
- {
- unsigned int *sem_id_p;
-
- MEM(sem_id_p = talloc(config, unsigned int));
- *sem_id_p = sem_id;
- talloc_set_destructor(sem_id_p, _exclusive_proc_close_sem);
-
+ config->multi_proc_sem_id = sem_id;
sem_initd = true;
- }
break;
case 1: /* another process has the semaphore */
//!< threaded mode.
bool allow_multiple_procs; //!< Allow multiple instances of radiusd to run with the
///< same config file.
+ unsigned int multi_proc_sem_id; //!< Semaphore we use to prevent multiple processes running.
uint32_t max_networks; //!< for the scheduler
uint32_t max_workers; //!< for the scheduler
void main_config_name_set_default(main_config_t *config, char const *name, bool overwrite_config);
void main_config_raddb_dir_set(main_config_t *config, char const *path);
void main_config_dict_dir_set(main_config_t *config, char const *path);
+
+void main_config_exclusive_proc_done(main_config_t const *config);
int main_config_exclusive_proc(main_config_t *config);
main_config_t *main_config_alloc(TALLOC_CTX *ctx);