+static void command_pre_select(struct sched *s, struct task *t)
+{
+ struct server_command_task *sct = container_of(t, struct server_command_task, task);
+ para_fd_set(sct->listen_fd, &s->rfds, &s->max_fileno);
+}
+
+static void command_post_select(struct sched *s, struct task *t)
+{
+ struct server_command_task *sct = container_of(t, struct server_command_task, task);
+
+ int new_fd, ret, i;
+ char *peer_name;
+ pid_t child_pid;
+ uint32_t *chunk_table;
+
+ ret = para_accept(sct->listen_fd, &s->rfds, NULL, 0, &new_fd);
+ if (ret <= 0)
+ goto out;
+ peer_name = remote_name(new_fd);
+ PARA_INFO_LOG("got connection from %s, forking\n", peer_name);
+ mmd->num_connects++;
+ mmd->active_connections++;
+ /*
+ * The chunk table is a pointer located in the mmd struct that points
+ * to dynamically allocated memory, i.e. it must be freed by the parent
+ * and the child. However, as the mmd struct is in a shared memory
+ * area, there's no guarantee that after the fork this pointer is still
+ * valid in child context. As it is not used in the child anyway, we
+ * save it to a local variable before the fork and free the memory via
+ * that copy in the child directly after the fork.
+ */
+ chunk_table = mmd->afd.afhi.chunk_table;
+ child_pid = fork();
+ if (child_pid < 0) {