1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
#include "memory.h"
#include "fiber.h"
#include "coio.h"
#include "coio_task.h"
#include "fio.h"
#include "unit.h"
#include "unit.h"
int
touch_f(va_list ap)
{
FILE *f = va_arg(ap, FILE *);
const char *c = "c";
while (true) {
int rc = fwrite(c, strlen(c), 1, f);
fail_unless(rc == 1);
fflush(f);
fiber_sleep(0.01);
if (fiber_is_cancelled())
return -1;
}
return 0;
}
static void
stat_notify_test(FILE *f, const char *filename)
{
header();
struct fiber *touch = fiber_new_xc("touch", touch_f);
fiber_start(touch, f);
ev_stat stat;
note("filename: %s", filename);
coio_stat_init(&stat, filename);
coio_stat_stat_timeout(&stat, TIMEOUT_INFINITY);
fail_unless(stat.prev.st_size < stat.attr.st_size);
fiber_cancel(touch);
footer();
}
static void
stat_timeout_test(const char *filename)
{
header();
ev_stat stat;
coio_stat_init(&stat, filename);
coio_stat_stat_timeout(&stat, 0.01);
footer();
}
static ssize_t
coio_test_wakeup(va_list ap)
{
usleep(1000);
return 0;
}
static int
test_call_f(va_list ap)
{
header();
int res = coio_call(coio_test_wakeup);
note("call done with res %i", res);
footer();
return res;
}
static void
test_getaddrinfo(void)
{
header();
plan(1);
const char *host = "127.0.0.1";
const char *port = "3333";
struct addrinfo *i;
/* NULL hints should work. It is a standard. */
int rc = coio_getaddrinfo(host, port, NULL, &i, 1);
is(rc, 0, "getaddrinfo");
freeaddrinfo(i);
/*
* gh-4209: 0 timeout should not be a special value and
* detach a task. Before a fix it led to segfault
* sometimes. The cycle below runs getaddrinfo multiple
* times to increase segfault probability.
*/
for (int j = 0; j < 5; ++j) {
if (coio_getaddrinfo(host, port, NULL, &i, 0) == 0 && i != NULL)
freeaddrinfo(i);
/*
* Skip one event loop to check, that the coio
* task destructor will not free the memory second
* time.
*/
fiber_sleep(0);
}
check_plan();
footer();
}
static int
main_f(va_list ap)
{
const char *filename = "1.out";
FILE *f = fopen(filename, "w+");
stat_timeout_test(filename);
stat_notify_test(f, filename);
fclose(f);
(void) remove(filename);
coio_enable();
struct fiber *call_fiber = fiber_new_xc("coio_call wakeup", test_call_f);
fiber_set_joinable(call_fiber, true);
fiber_start(call_fiber);
fiber_wakeup(call_fiber);
fiber_cancel(call_fiber);
fiber_join(call_fiber);
test_getaddrinfo();
ev_break(loop(), EVBREAK_ALL);
return 0;
}
int main()
{
memory_init();
fiber_init(fiber_cxx_invoke);
struct fiber *test = fiber_new_xc("coio_stat", main_f);
fiber_wakeup(test);
ev_run(loop(), 0);
fiber_free();
memory_free();
return 0;
}
|