first version of the universal paraslash scheduler
[paraslash.git] / file_writer.c
index a7a765e1175c6379e1881973faa9553255a3cd40..d8fb3e54b5b2c43df4e4af1a670ba6c97ec2546a 100644 (file)
 /** \file file_writer.c simple output plugin for testing purposes */
 
 #include "para.h"
+#include "list.h"
+#include "sched.h"
 #include "write.h"
 #include "string.h"
+#include "fd.h"
 #include "error.h"
 
 /** data specific to the file writer */
 struct private_file_writer_data {
 /** the file descriptor of the output file */
 int fd;
+int check_fd;
 };
 
-static int file_writer_open(struct writer_node *w)
+static int file_writer_open(struct writer_node *wn)
 {
        struct private_file_writer_data *pfwd = para_calloc(
                sizeof(struct private_file_writer_data));
@@ -38,7 +42,7 @@ static int file_writer_open(struct writer_node *w)
 
        free(home);
        free(tmp);
-       w->private_data = pfwd;
+       wn->private_data = pfwd;
        pfwd->fd = open(filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
        free(filename);
        if (pfwd->fd >= 0)
@@ -56,6 +60,44 @@ static int file_writer_write(char *data, size_t nbytes, struct writer_node *wn)
        return ret;
 }
 
+static void file_writer_pre_select(struct sched *s, struct task *t)
+{
+       struct writer_node *wn = t->private_data;
+       struct private_file_writer_data *pfwd = wn->private_data;
+       struct writer_node_group *wng = wn->wng;
+
+//     PARA_INFO_LOG("task %p check_fd: %d\n", t, pfwd->check_fd);
+       pfwd->check_fd = 0;
+       t->ret = -E_FW_NO_FILE;
+       if (pfwd->fd <= 0)
+               return;
+       t->ret = 0;
+       if (!*wng->loaded)
+               return;
+       t->ret = 1;
+       para_fd_set(pfwd->fd, &s->wfds, &s->max_fileno);
+       pfwd->check_fd = 1;
+}
+
+static void file_writer_post_select(struct sched *s, struct task *t)
+{
+       struct writer_node *wn = t->private_data;
+       struct private_file_writer_data *pfwd = wn->private_data;
+       struct writer_node_group *wng = wn->wng;
+
+       t->ret = 0;
+       if (!pfwd->check_fd)
+               return;
+       if (!*wng->loaded)
+               return;
+       if (!FD_ISSET(pfwd->fd, &s->wfds))
+               return;
+//     PARA_INFO_LOG("writing %zd\n", *wng->loaded);
+       t->ret = write(pfwd->fd, wng->buf, *wng->loaded);
+       if (t->ret < 0)
+               t->ret = -E_FW_WRITE;
+}
+
 static void file_writer_close(struct writer_node *wn)
 {
        struct private_file_writer_data *pfwd = wn->private_data;
@@ -68,6 +110,8 @@ void file_writer_init(struct writer *w)
 {
        w->open = file_writer_open;
        w->write = file_writer_write;
+       w->pre_select = file_writer_pre_select;
+       w->post_select = file_writer_post_select;
        w->close = file_writer_close;
        w->shutdown = NULL; /* nothing to do */
 }