File: coio.cc

package info (click to toggle)
tarantool 2.6.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 85,364 kB
  • sloc: ansic: 513,760; cpp: 69,489; sh: 25,650; python: 19,190; perl: 14,973; makefile: 4,173; yacc: 1,329; sql: 1,074; pascal: 620; ruby: 190; awk: 18; lisp: 7
file content (139 lines) | stat: -rw-r--r-- 2,660 bytes parent folder | download | duplicates (3)
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;
}