- ret = attribute_init(&afs_tables[TBLNUM_ATTRIBUTES]);
- if (ret < 0)
- goto attribute_init_error;
- ret = moods_init(&afs_tables[TBLNUM_MOODS]);
- if (ret < 0)
- goto moods_init_error;
- ret = playlists_init(&afs_tables[TBLNUM_PLAYLIST]);
- if (ret < 0)
- goto playlists_init_error;
- ret = lyrics_init(&afs_tables[TBLNUM_LYRICS]);
- if (ret < 0)
- goto lyrics_init_error;
- ret = images_init(&afs_tables[TBLNUM_IMAGES]);
- if (ret < 0)
- goto images_init_error;
- ret = score_init(&afs_tables[TBLNUM_SCORES]);
- if (ret < 0)
- goto score_init_error;
- ret = aft_init(&afs_tables[TBLNUM_AUDIO_FILES]);
- if (ret < 0)
- goto aft_init_error;
+static int open_afs_tables(void)
+{
+ int i, ret;
+
+ get_database_dir();
+ PARA_NOTICE_LOG("opening %u osl tables in %s\n", NUM_AFS_TABLES,
+ database_dir);
+ for (i = 0; i < NUM_AFS_TABLES; i++) {
+ ret = afs_tables[i].open(database_dir);
+ if (ret >= 0)
+ continue;
+ PARA_ERROR_LOG("%s init: %s\n", afs_tables[i].name,
+ para_strerror(-ret));
+ break;
+ }
+ if (ret >= 0)
+ return ret;
+ while (i)
+ afs_tables[--i].close();
+ return ret;
+}
+
+static void signal_pre_select(struct sched *s, struct task *t)
+{
+ struct signal_task *st = container_of(t, struct signal_task, task);
+ para_fd_set(st->fd, &s->rfds, &s->max_fileno);
+}
+
+static void afs_signal_post_select(struct sched *s, struct task *t)
+{
+ struct signal_task *st = container_of(t, struct signal_task, task);
+ if (getppid() == 1) {
+ PARA_EMERG_LOG("para_server died\n");
+ goto shutdown;
+ }
+ if (!FD_ISSET(st->fd, &s->rfds))
+ return;
+ st->signum = para_next_signal();
+ if (st->signum == SIGHUP) {
+ close_afs_tables();
+ parse_config_or_die(1);
+ t->error = open_afs_tables();
+ if (t->error < 0)
+ return;
+ init_admissible_files(current_mop);
+ return;
+ }
+ PARA_EMERG_LOG("terminating on signal %d\n", st->signum);
+shutdown:
+ sched_shutdown();
+ t->error = -E_AFS_SIGNAL;
+}
+
+static void register_signal_task(void)
+{
+ struct signal_task *st = &signal_task_struct;
+
+ para_sigaction(SIGPIPE, SIG_IGN);
+ st->fd = para_signal_init();
+ PARA_INFO_LOG("signal pipe: fd %d\n", st->fd);
+ para_install_sighandler(SIGINT);
+ para_install_sighandler(SIGTERM);
+ para_install_sighandler(SIGHUP);
+
+ st->task.pre_select = signal_pre_select;
+ st->task.post_select = afs_signal_post_select;
+ sprintf(st->task.status, "signal task");
+ register_task(&st->task);
+}
+
+static struct list_head afs_client_list;