]> mj.ucw.cz Git - libucw.git/blob - ucw/main-test.c
Main: Let main-block use HOOK_RETRY / HOOK_IDLE as suggested by the docs
[libucw.git] / ucw / main-test.c
1 /*
2  *      UCW Library -- Main Loop: Testing
3  *
4  *      (c) 2004--2011 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #include "ucw/lib.h"
11 #include "ucw/mainloop.h"
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <unistd.h>
16
17 #ifdef TEST
18
19 static struct main_process mp;
20 static struct main_block_io fin, fout;
21 static struct main_hook hook;
22 static struct main_timer tm;
23 static struct main_signal sg;
24 static int sig_counter;
25
26 static byte rb[16];
27
28 static void dread(struct main_block_io *bio)
29 {
30   if (bio->rpos < bio->rlen)
31     {
32       msg(L_INFO, "Read EOF");
33       bio->data = NULL; // Mark as deleted
34       block_io_del(bio);
35     }
36   else
37     {
38       msg(L_INFO, "Read done");
39       block_io_read(bio, rb, sizeof(rb));
40       block_io_set_timeout(&fin, 3000);
41     }
42 }
43
44 static void derror(struct main_block_io *bio, int cause)
45 {
46   msg(L_INFO, "Error: %m !!! (cause %d)", cause);
47   bio->data = NULL;
48   block_io_del(bio);
49 }
50
51 static void dwrite(struct main_block_io *bio UNUSED)
52 {
53   msg(L_INFO, "Write done");
54 }
55
56 static int dhook(struct main_hook *ho UNUSED)
57 {
58   msg(L_INFO, "Hook called");
59   if (sig_counter >= 3)
60     return HOOK_SHUTDOWN;
61   return 0;
62 }
63
64 static void dtimer(struct main_timer *tm)
65 {
66   msg(L_INFO, "Timer tick");
67   timer_add_rel(tm, 11000);
68   timer_add_rel(tm, 10000);
69 }
70
71 static void dentry(void)
72 {
73   log_fork();
74   main_teardown();
75   msg(L_INFO, "*** SUBPROCESS START ***");
76   sleep(2);
77   msg(L_INFO, "*** SUBPROCESS FINISH ***");
78   exit(0);
79 }
80
81 static void dexit(struct main_process *pr)
82 {
83   msg(L_INFO, "Subprocess %d exited with status %x", pr->pid, pr->status);
84 }
85
86 static void dsignal(struct main_signal *sg UNUSED)
87 {
88   msg(L_INFO, "SIGINT received (send 3 times to really quit, or use Ctrl-\\)");
89   sig_counter++;
90 }
91
92 int
93 main(void)
94 {
95   log_init(NULL);
96   main_init();
97
98   fin.read_done = dread;
99   fin.error_handler = derror;
100   fin.data = "";
101   block_io_add(&fin, 0);
102   block_io_read(&fin, rb, sizeof(rb));
103
104   fout.write_done = dwrite;
105   fout.error_handler = derror;
106   fout.data = "";
107   block_io_add(&fout, 1);
108   block_io_write(&fout, "Hello, world!\n", 14);
109
110   hook.handler = dhook;
111   hook_add(&hook);
112
113   tm.handler = dtimer;
114   timer_add_rel(&tm,  1000);
115
116   sg.signum = SIGINT;
117   sg.handler = dsignal;
118   signal_add(&sg);
119
120   mp.handler = dexit;
121   if (!process_fork(&mp))
122     dentry();
123
124   main_debug();
125
126   main_loop();
127   msg(L_INFO, "Finished.");
128
129   if (fin.data)
130     block_io_del(&fin);
131   if (fout.data)
132     block_io_del(&fout);
133   hook_del(&hook);
134   signal_del(&sg);
135   timer_del(&tm);
136   main_cleanup();
137   return 0;
138 }
139
140 #endif