├── LICENSE
├── Makefile
├── README.md
├── demo
├── Makefile
├── demo_all_sort.cc
├── demo_any_sort.cc
└── demo_http_server.cc
├── deps
├── gyp.zip
├── hiredis-0.11.0u2.zip
└── libuv-0.10.27.zip
├── docs
├── buttondown.css
└── index.html
├── extensions
├── http
│ ├── Makefile
│ └── cocoflow-http.cc
├── redis
│ ├── Makefile
│ └── cocoflow-redis.cc
├── test
│ ├── Makefile
│ ├── test_http_get.cc
│ ├── test_http_post.cc
│ ├── test_redis.cc
│ └── test_redis2.cc
├── vc
│ ├── cocoflow-extensions.sln
│ ├── libccf-http.vcproj
│ ├── test_http_get.vcproj
│ └── test_http_post.vcproj
└── vcbuild.bat
├── include
├── cocoflow-http.h
├── cocoflow-redis.h
└── cocoflow.h
├── lib
└── chishaxie
├── src
├── Makefile
├── cocoflow-comm.h
├── cocoflow.cc
├── getaddrinfo.cc
├── max_map_count.c
├── max_map_count.h
├── sleep.cc
├── sync.cc
├── tcp.cc
├── tools.cc
└── udp.cc
├── test
├── Makefile
├── benchmark_sleep.cc
├── benchmark_tcp.cc
├── benchmark_udp.cc
├── benchmark_udp2.cc
├── simple_rand.h
├── test_getaddrinfo.cc
├── test_primitive.cc
├── test_sleep.cc
├── test_tcp.cc
├── test_tcp2.cc
├── test_tcp3.cc
├── test_udp.cc
├── test_udp2.cc
├── test_udp3.cc
├── uc_benchmark
│ ├── Makefile
│ ├── switch_diff.cc
│ ├── switch_diff_big_stack.cc
│ ├── switch_diff_middle_stack.cc
│ ├── switch_diff_small_stack.cc
│ ├── switch_diff_super_big_stack.cc
│ ├── switch_in_ping_pong.cc
│ └── switch_new.cc
└── unexpected_tcp_timing.cc
├── vc
├── benchmark_sleep.vcproj
├── benchmark_tcp.vcproj
├── benchmark_udp.vcproj
├── benchmark_udp2.vcproj
├── cocoflow.sln
├── demo_all_sort.vcproj
├── demo_any_sort.vcproj
├── demo_http_server.vcproj
├── libccf.vcproj
├── test.bat
├── test_getaddrinfo.vcproj
├── test_primitive.vcproj
├── test_sleep.vcproj
├── test_tcp.vcproj
├── test_tcp2.vcproj
├── test_tcp3.vcproj
├── test_udp.vcproj
├── test_udp2.vcproj
├── test_udp3.vcproj
├── test_x64.bat
└── unexpected_tcp_timing.vcproj
└── vcbuild.bat
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | LIB = lib/libuv.a lib/libccf.a
2 | DEMO = demo/demo_all_sort demo/demo_any_sort demo/demo_http_server
3 | TEST = test/test_primitive test/test_sleep test/test_udp test/test_udp2 test/test_udp3 test/test_tcp test/test_tcp2 test/test_tcp3 test/benchmark_udp test/benchmark_udp2 test/benchmark_tcp
4 |
5 | top: $(LIB)
6 | all: $(LIB) $(DEMO) $(TEST)
7 |
8 | $(LIB): src/cocoflow.cc include/cocoflow.h
9 | make -C src
10 |
11 | $(DEMO): demo/*.cc
12 | make -C demo
13 |
14 | $(TEST): test/*.cc
15 | make -C test
16 |
17 | .PHONY: clean test del
18 |
19 | clean:
20 | make -C src clean
21 | make -C demo clean
22 | make -C test clean
23 |
24 | test: $(TEST)
25 | make -C test all_test
26 |
27 | del: $(LIB)
28 | cp lib/libuv.a libuv.a
29 | cp lib/libccf.a libccf.a
30 | cp include/cocoflow.h cocoflow.h
31 | rm -rf include/ lib/ src/ demo/ test/ deps/ docs/ extensions/ test/ vc/ Makefile README.md vcbuild.bat
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Concurrency Control Flow 并发流程控制
2 | ========
3 |
4 | A C++ framework is based on coroutine and libuv, just using **start**, **await**, **all_of**, **any_of** to control flow.
5 |
6 | 一个基于协程和libuv的C++框架,仅通过 **start**、 **await**、 **all_of**、 **any_of** 控制流程。
7 |
8 | * 示例:你需要等待两个udp的recv事件,并且需要设置一个超时时间,则你可以用使用:
9 |
10 | ###
11 | await (
12 | any_of (
13 | all_of (
14 | udp0.recv,
15 | udp1.recv
16 | ),
17 | sleep(x ms)
18 | )
19 | )
20 |
21 | ### Documents: [wiki](https://github.com/chishaxie/cocoflow/wiki)
22 |
23 | ### To build:
24 |
25 | Prerequisites (Linux):
26 |
27 | * GCC 4.2 or newer
28 | * Python 2.6 or 2.7
29 | * GNU Make 3.81 or newer
30 | * (All of above is for libuv)
31 |
32 | Linux:
33 |
34 | make
35 |
36 | Prerequisites (Windows):
37 |
38 | * UnZip (You can extract dependencies by other tools)
39 | * Python 2.6 or 2.7
40 | * Visual Studio 2008 or 2010 or 2012 or 2013
41 |
42 | Windows:
43 |
44 | run vcbuild.bat
45 |
46 | ### To run the tests:
47 |
48 | Linux:
49 |
50 | make test
51 |
52 | Windows:
53 |
54 | run vc\test.bat (for Win32)
55 | run vc\test_x64.bat (for Win64)
56 |
57 | ### License
58 |
59 | (The LGPL License)
60 |
--------------------------------------------------------------------------------
/demo/Makefile:
--------------------------------------------------------------------------------
1 | C_ARGS = -g -Wall -O2
2 | CX = g++
3 |
4 | LIB = ../lib/libuv.a ../lib/libccf.a
5 | BIN = demo_all_sort demo_any_sort demo_http_server
6 |
7 | LIB_ARGS = -L../lib -lccf -luv -lpthread -lrt
8 | INC_ARGS = -I../include
9 |
10 | all: $(BIN)
11 |
12 | $(LIB):
13 | make -C ../src/
14 |
15 | demo_all_sort: demo_all_sort.cc $(LIB)
16 | $(CX) $(C_ARGS) -o $@ demo_all_sort.cc $(LIB_ARGS) $(INC_ARGS)
17 |
18 | demo_any_sort: demo_any_sort.cc $(LIB)
19 | $(CX) $(C_ARGS) -o $@ demo_any_sort.cc $(LIB_ARGS) $(INC_ARGS)
20 |
21 | demo_http_server: demo_http_server.cc $(LIB)
22 | $(CX) $(C_ARGS) -o $@ demo_http_server.cc $(LIB_ARGS) $(INC_ARGS)
23 |
24 | .PHONY: clean
25 | clean:
26 | rm -f $(BIN)
27 |
--------------------------------------------------------------------------------
/demo/demo_all_sort.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "cocoflow.h"
4 |
5 | using namespace std;
6 |
7 | #define WAITING_TIME 1000
8 |
9 | class sort_task: public ccf::user_task
10 | {
11 | protected:
12 | int vals[10];
13 | int num;
14 | bool right;
15 | void show_cur_vals(int compare_a = -1, int compare_b = -1, int _small = -1, int _large = -1)
16 | {
17 | #if defined(_WIN32) || defined(_WIN64)
18 | compare_a = compare_b = _small = _large = -1;
19 | #endif
20 | ccf::sleep waiting(2 * WAITING_TIME);
21 | await(waiting);
22 | if (this->right) cout << " ";
23 | for (int i=0; inum; i++)
24 | {
25 | if (_small == i) cout << "\033[1;31m";
26 | else if (_large == i) cout << "\033[1;34m";
27 | else if (compare_a == i || compare_b == i) cout << "\033[1;32m";
28 | cout << vals[i] << " ";
29 | if (compare_a == i || compare_b == i || _small == i || _large == i) cout << "\033[0m";
30 | }
31 | cout << endl;
32 | }
33 | void init(bool right)
34 | {
35 | this->right = right;
36 | this->num = 10;
37 | vals[0] = 9; vals[1] = 5; vals[2] = 11; vals[3] = 7; vals[4] = 2;
38 | vals[5] = 21; vals[6] = 8; vals[7] = 4; vals[8] = 15; vals[9] = 9;
39 | }
40 | };
41 |
42 | class bubble_sort_task: public sort_task
43 | {
44 | void run()
45 | {
46 | this->init(false);
47 | this->show_cur_vals();
48 | for (int i=0; inum-1; i++)
49 | {
50 | bool change = false;
51 | for (int j=this->num-1; j>=i; j--)
52 | {
53 | this->show_cur_vals(j, j-1);
54 | if (vals[j] < vals[j-1])
55 | {
56 | int tmp = vals[j];
57 | vals[j] = vals[j-1];
58 | vals[j-1] = tmp;
59 | change = true;
60 | this->show_cur_vals(-1, -1, j-1, j);
61 | }
62 | }
63 | if (!change)
64 | break;
65 | }
66 | }
67 | };
68 |
69 | class select_sort_task: public sort_task
70 | {
71 | void run()
72 | {
73 | ccf::sleep waiting(WAITING_TIME);
74 | await(waiting);
75 | this->init(true);
76 | this->show_cur_vals();
77 | for (int i=0; inum-1; i++)
78 | {
79 | int min = i;
80 | for (int j=i+1; jnum; j++)
81 | {
82 | this->show_cur_vals(i, j, min);
83 | if (vals[min] > vals[j])
84 | {
85 | min = j;
86 | this->show_cur_vals(i, j, min);
87 | }
88 | }
89 | if (min != i)
90 | {
91 | int tmp = vals[i];
92 | vals[i] = vals[min];
93 | vals[min] = tmp;
94 | this->show_cur_vals(-1, -1, i, min);
95 | }
96 | }
97 | }
98 | };
99 |
100 | class main_task: public ccf::user_task
101 | {
102 | void run()
103 | {
104 | cout << "BubbleSort (left) SelectSort (right)" << endl;
105 | bubble_sort_task b;
106 | select_sort_task s;
107 | ccf::all_of all(b, s);
108 | await(all);
109 | }
110 | };
111 |
112 | int main()
113 | {
114 | ccf::event_task::init(100);
115 | ccf::user_task::init(100);
116 |
117 | //ccf::set_debug(stderr);
118 |
119 | main_task tMain;
120 | ccf::cocoflow(tMain);
121 | return 0;
122 | }
123 |
--------------------------------------------------------------------------------
/demo/demo_any_sort.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "cocoflow.h"
4 |
5 | using namespace std;
6 |
7 | #define WAITING_TIME 1000
8 |
9 | class sort_task: public ccf::user_task
10 | {
11 | protected:
12 | int vals[10];
13 | int num;
14 | bool right;
15 | void show_cur_vals(int compare_a = -1, int compare_b = -1, int _small = -1, int _large = -1)
16 | {
17 | #if defined(_WIN32) || defined(_WIN64)
18 | compare_a = compare_b = _small = _large = -1;
19 | #endif
20 | ccf::sleep waiting(2 * WAITING_TIME);
21 | await(waiting);
22 | if (this->right) cout << " ";
23 | for (int i=0; inum; i++)
24 | {
25 | if (_small == i) cout << "\033[1;31m";
26 | else if (_large == i) cout << "\033[1;34m";
27 | else if (compare_a == i || compare_b == i) cout << "\033[1;32m";
28 | cout << vals[i] << " ";
29 | if (compare_a == i || compare_b == i || _small == i || _large == i) cout << "\033[0m";
30 | }
31 | cout << endl;
32 | }
33 | void init(bool right)
34 | {
35 | this->right = right;
36 | this->num = 10;
37 | vals[0] = 9; vals[1] = 5; vals[2] = 11; vals[3] = 7; vals[4] = 2;
38 | vals[5] = 21; vals[6] = 8; vals[7] = 4; vals[8] = 15; vals[9] = 9;
39 | }
40 | };
41 |
42 | class bubble_sort_task: public sort_task
43 | {
44 | void run()
45 | {
46 | this->init(false);
47 | this->show_cur_vals();
48 | for (int i=0; inum-1; i++)
49 | {
50 | bool change = false;
51 | for (int j=this->num-1; j>=i; j--)
52 | {
53 | this->show_cur_vals(j, j-1);
54 | if (vals[j] < vals[j-1])
55 | {
56 | int tmp = vals[j];
57 | vals[j] = vals[j-1];
58 | vals[j-1] = tmp;
59 | change = true;
60 | this->show_cur_vals(-1, -1, j-1, j);
61 | }
62 | }
63 | if (!change)
64 | break;
65 | }
66 | }
67 | void cancel()
68 | {
69 | cout << "BubbleSort is canceled" << endl;
70 | }
71 | };
72 |
73 | class select_sort_task: public sort_task
74 | {
75 | void run()
76 | {
77 | ccf::sleep waiting(WAITING_TIME);
78 | await(waiting);
79 | this->init(true);
80 | this->show_cur_vals();
81 | for (int i=0; inum-1; i++)
82 | {
83 | int min = i;
84 | for (int j=i+1; jnum; j++)
85 | {
86 | this->show_cur_vals(i, j, min);
87 | if (vals[min] > vals[j])
88 | {
89 | min = j;
90 | this->show_cur_vals(i, j, min);
91 | }
92 | }
93 | if (min != i)
94 | {
95 | int tmp = vals[i];
96 | vals[i] = vals[min];
97 | vals[min] = tmp;
98 | this->show_cur_vals(-1, -1, i, min);
99 | }
100 | }
101 | }
102 | void cancel()
103 | {
104 | cout << "SelectSort is canceled" << endl;
105 | }
106 | };
107 |
108 | class main_task: public ccf::user_task
109 | {
110 | void run()
111 | {
112 | cout << "BubbleSort (left) SelectSort (right)" << endl;
113 | bubble_sort_task b;
114 | select_sort_task s;
115 | ccf::any_of any(b, s);
116 | await(any);
117 | }
118 | };
119 |
120 | int main()
121 | {
122 | ccf::event_task::init(100);
123 | ccf::user_task::init(100);
124 |
125 | //ccf::set_debug(stderr);
126 |
127 | main_task tMain;
128 | ccf::cocoflow(tMain);
129 | return 0;
130 | }
131 |
--------------------------------------------------------------------------------
/demo/demo_http_server.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "cocoflow.h"
5 |
6 | using namespace std;
7 |
8 | static int port = 1337;
9 |
10 | typedef ccf::task<7> my_task;
11 |
12 | class http_task: public my_task
13 | {
14 | public:
15 | ccf::tcp::connected http_connection;
16 | private:
17 | void run()
18 | {
19 | int ret;
20 | char req_buf[3072], res_buf[1024];
21 | size_t req_len = sizeof(req_buf), res_len = 0, tmp;
22 | ccf::tcp::recv_till recv_task(ret, http_connection, req_buf, req_len, "\r\n\r\n", 4);
23 | await(recv_task);
24 | if (ret == ccf::tcp::success)
25 | {
26 | do {
27 | tmp = res_len;
28 | res_len = sprintf(res_buf, "HTTP/1.0 200 OK\r\nServer: cocoflow-http-server\r\nContent-Type: text/plain\r\nContent-Length: %u\r\n\r\n", (unsigned)(req_len + tmp + 36));
29 | } while(res_len != tmp);
30 | ccf::tcp::send send_task(ret, http_connection, res_buf, res_len, req_buf, req_len, "--------------------------------\r\n\r\n", 36, res_buf, res_len);
31 | await(send_task);
32 | }
33 | }
34 | };
35 |
36 | class main_task: public my_task
37 | {
38 | void run()
39 | {
40 | ccf::tcp::listening http_server;
41 | if (http_server.bind(ccf::ip_to_addr("0.0.0.0", port)) != 0)
42 | {
43 | perror("Bind socket");
44 | exit(1);
45 | }
46 | for (;;)
47 | {
48 | int ret;
49 | http_task *new_http_task = new http_task();
50 | ccf::tcp::accept accept_task(ret, http_server, new_http_task->http_connection);
51 | await(accept_task);
52 | if (ret != ccf::tcp::success)
53 | break;
54 | ccf::start(new_http_task);
55 | }
56 | }
57 | };
58 |
59 | int main(int argc, char *argv[])
60 | {
61 | if (argc > 2)
62 | port = atoi(argv[1]);
63 |
64 | my_task::init(1025);
65 | ccf::event_task::init(4);
66 |
67 | main_task my_main;
68 |
69 | ccf::cocoflow(my_main);
70 |
71 | return 0;
72 | }
73 |
--------------------------------------------------------------------------------
/deps/gyp.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chishaxie/cocoflow/4c7c0978940b398d972150ee5b0f0ad8530c396f/deps/gyp.zip
--------------------------------------------------------------------------------
/deps/hiredis-0.11.0u2.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chishaxie/cocoflow/4c7c0978940b398d972150ee5b0f0ad8530c396f/deps/hiredis-0.11.0u2.zip
--------------------------------------------------------------------------------
/deps/libuv-0.10.27.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chishaxie/cocoflow/4c7c0978940b398d972150ee5b0f0ad8530c396f/deps/libuv-0.10.27.zip
--------------------------------------------------------------------------------
/docs/buttondown.css:
--------------------------------------------------------------------------------
1 | div#header,header{border-bottom:1px solid #aaa;margin-bottom:0.5em;}.title{text-align:center;}.author,.date{text-align:center;}div#TOC,nav#TOC{border-bottom:1px solid #aaa;margin-bottom:0.5em;}@media print{div#TOC,nav#TOC{display:none;}}h1,h2,h3,h4,h5,h6{font-family:"Helvetica Neue",Helvetica,"Liberation Sans",Calibri,Arial,sans-serif;page-break-after:avoid;}div div,section section{margin-left:2em;}p{}blockquote{font-style:italic;}li{}li > p{margin-top:1em;}ul{}ul li{}ol{}ol li{}hr{}sub{}sup{}em{}em > em{font-style:normal;}strong{}a{text-decoration:none;}@media screen{a:hover{text-decoration:underline;}}@media print{a{color:black;background:transparent;}a[href^="http://"]:after,a[href^="https://"]:after{content:" (" attr(href) ") ";font-size:90%;}}img{vertical-align:middle;}div.figure{margin-left:auto;margin-right:auto;text-align:center;font-style:italic;}p.caption{}pre,code{background-color:#fdf7ee;white-space:pre-wrap;white-space:-moz-pre-wrap !important;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word;}pre{padding:0.5em;border-radius:5px;border:1px solid #aaa;margin-left:0.5em;margin-right:0.5em;}@media screen{pre{white-space:pre;overflow:auto;border:1px dotted #777;}}code{}p > code,li > code{padding-left:2px;padding-right:2px;}li > p code{padding:2px;}span.math{}div.math{}span.LaTeX{}eq{}table{border-collapse:collapse;border-spacing:0;border-bottom:2pt solid #000;border-top:2pt solid #000;margin-left:auto;margin-right:auto;}thead{border-bottom:1pt solid #000;background-color:#eee;}tr.header{}tbody{}tr{}tr.odd:hover,tr.even:hover{background-color:#eee;}tr.odd{}tr.even{}td,th{vertical-align:top;vertical-align:baseline;padding-left:0.5em;padding-right:0.5em;padding-top:0.2em;padding-bottom:0.2em;}th{font-weight:bold;}tfoot{}caption{caption-side:top;border:none;font-size:0.9em;font-style:italic;text-align:center;margin-bottom:0.3em;padding-bottom:0.2em;}dl{border-top:2pt solid black;padding-top:0.5em;border-bottom:2pt solid black;}dt{font-weight:bold;}dd+dt{border-top:1pt solid black;padding-top:0.5em;}dd{margin-bottom:0.5em;}dd+dd{border-top:1px solid black;}a.footnote,a.footnoteRef{font-size:small;vertical-align:text-top;}a[href^="#fnref"],a.reversefootnote{}@media print{a[href^="#fnref"],a.reversefootnote{display:none;}}div.footnotes{}div.footnotes li[id^="fn"]{}@media print{.noprint{display:none;}}
--------------------------------------------------------------------------------
/extensions/http/Makefile:
--------------------------------------------------------------------------------
1 | C_ARGS = -g -Wall -O2
2 | CX = g++
3 |
4 | LIB = ../../lib/libccf-http.a
5 |
6 | INC_ARGS = -I../../include -I../../src -I../../src/uv
7 |
8 | all: $(LIB)
9 |
10 | ../../lib/libccf-http.a: cocoflow-http.o
11 | ar cr $@ $^
12 |
13 | cocoflow-http.o: cocoflow-http.cc ../../src/cocoflow-comm.h ../../include/cocoflow.h ../../include/cocoflow-http.h ../../src/uv/uv.h
14 | $(CX) $(C_ARGS) -fPIC -c -o $@ cocoflow-http.cc $(INC_ARGS)
15 |
16 | ../../src/uv/uv.h:
17 | make -C ../../src/
18 |
19 | .PHONY: clean
20 | clean:
21 | rm -f $(LIB) *.o
22 |
--------------------------------------------------------------------------------
/extensions/redis/Makefile:
--------------------------------------------------------------------------------
1 | C_ARGS = -g -Wall -O2
2 | CX = g++
3 |
4 | LIB = ../../lib/libccf-redis.a
5 |
6 | HIREDIS_DEPS=../../deps/hiredis-0.11.0u2
7 |
8 | HIREDIS_OBJ = net.o hiredis.o sds.o async.o
9 | HIREDIS_OBJ_DEPS = $(HIREDIS_DEPS)/net.o $(HIREDIS_DEPS)/hiredis.o $(HIREDIS_DEPS)/sds.o $(HIREDIS_DEPS)/async.o
10 |
11 | INC_ARGS = -I../../include -I../../src -I../../src/uv -I$(HIREDIS_DEPS)
12 |
13 | all: $(LIB)
14 |
15 | ../../lib/libccf-redis.a: $(HIREDIS_OBJ) cocoflow-redis.o
16 | ar cr $@ $^
17 |
18 | $(HIREDIS_OBJ): $(HIREDIS_OBJ_DEPS)
19 | cp $(HIREDIS_OBJ_DEPS) .
20 |
21 | cocoflow-redis.o: cocoflow-redis.cc ../../src/cocoflow-comm.h ../../include/cocoflow.h ../../include/cocoflow-redis.h ../../src/uv/uv.h
22 | $(CX) $(C_ARGS) -fPIC -c -o $@ cocoflow-redis.cc $(INC_ARGS)
23 |
24 | ../../src/uv/uv.h:
25 | make -C ../../src/
26 |
27 | $(HIREDIS_OBJ_DEPS): $(HIREDIS_DEPS).zip
28 | @echo "Dependency analysis ..."
29 | @cd ../../deps/; unzip hiredis-0.11.0u2.zip > /dev/null; cd ../extensions/redis/
30 | @echo "Compiling hiredis ..."
31 | @make -C $(HIREDIS_DEPS) > /dev/null
32 | @echo "Compiled hiredis"
33 |
34 | .PHONY: clean
35 | clean:
36 | rm -f $(LIB) *.o
37 |
--------------------------------------------------------------------------------
/extensions/test/Makefile:
--------------------------------------------------------------------------------
1 | C_ARGS = -g -Wall -O2
2 | CX = g++
3 |
4 | LIB = ../../lib/libuv.a ../../lib/libccf.a
5 | BIN = test_redis test_redis2 test_http_get test_http_post
6 |
7 | LIB_ARGS = -L../../lib -lccf -luv -lpthread -lrt
8 | INC_ARGS = -I../../include
9 |
10 | LIB_REDIS = ../../lib/libccf-redis.a
11 | LIB_REDIS_ARGS = -lccf-redis
12 |
13 | LIB_HTTP = ../../lib/libccf-http.a
14 | LIB_HTTP_ARGS = -lccf-http
15 |
16 | all: $(BIN)
17 |
18 | $(LIB):
19 | make -C ../../src/
20 |
21 | $(LIB_REDIS):
22 | make -C ../redis/
23 |
24 | $(LIB_HTTP):
25 | make -C ../http/
26 |
27 | test_redis: test_redis.cc $(LIB) $(LIB_REDIS)
28 | $(CX) $(C_ARGS) -o $@ test_redis.cc $(LIB_REDIS_ARGS) $(LIB_ARGS) $(INC_ARGS)
29 | test_redis2: test_redis2.cc $(LIB) $(LIB_REDIS)
30 | $(CX) $(C_ARGS) -o $@ test_redis2.cc $(LIB_REDIS_ARGS) $(LIB_ARGS) $(INC_ARGS)
31 |
32 | test_http_get: test_http_get.cc $(LIB) $(LIB_HTTP)
33 | $(CX) $(C_ARGS) -o $@ test_http_get.cc $(LIB_HTTP_ARGS) $(LIB_ARGS) $(INC_ARGS)
34 | test_http_post: test_http_post.cc $(LIB) $(LIB_HTTP)
35 | $(CX) $(C_ARGS) -o $@ test_http_post.cc $(LIB_HTTP_ARGS) $(LIB_ARGS) $(INC_ARGS)
36 |
37 | .PHONY: clean
38 | clean:
39 | rm -f $(BIN)
40 |
41 | .PHONY: test
42 |
43 | test: $(BIN)
44 | @echo 'test redis'
45 | @(./test_redis > /dev/null && echo 'Succeed') || echo 'Failed'
46 |
--------------------------------------------------------------------------------
/extensions/test/test_http_get.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include
4 |
5 | #include "cocoflow.h"
6 | #include "cocoflow-http.h"
7 |
8 | using namespace std;
9 |
10 | static char *url = NULL;
11 | static char *buf = NULL;
12 | static size_t size = 1048576;
13 |
14 | class main_task: public ccf::user_task
15 | {
16 | void run()
17 | {
18 | int ret;
19 | const char *errmsg;
20 |
21 | ccf::http::get GET(ret, &errmsg, url, buf, size);
22 | await(GET);
23 |
24 | cerr << "Status Code: " << ret << endl;
25 | if (errmsg)
26 | cerr << "Reason Phrase: " << errmsg << endl;
27 | cerr << "Body Length: " << size << endl;
28 | if (size)
29 | {
30 | buf[size] = '\0';
31 | cout << buf << endl;
32 | }
33 | }
34 | };
35 |
36 | int main(int argc, char *argv[])
37 | {
38 | if (argc < 2)
39 | {
40 | cerr << "Usage: " << argv[0] << " [bufsize=1048576]" << endl;
41 | return 1;
42 | }
43 |
44 | url = argv[1];
45 | if (argc > 2)
46 | size = atoi(argv[2]);
47 |
48 | if (size)
49 | {
50 | buf = reinterpret_cast(malloc(size + 1));
51 | if (!buf)
52 | return 2;
53 | }
54 |
55 | ccf::event_task::init(100);
56 | ccf::user_task::init(100);
57 |
58 | //ccf::set_debug(stderr);
59 |
60 | main_task tMain;
61 | ccf::cocoflow(tMain);
62 | return 0;
63 | }
64 |
--------------------------------------------------------------------------------
/extensions/test/test_http_post.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include
4 | #include
5 |
6 | #include "cocoflow.h"
7 | #include "cocoflow-http.h"
8 |
9 | using namespace std;
10 |
11 | static char *url = NULL;
12 | static char *buf = NULL;
13 | static size_t size = 1048576;
14 | static string data;
15 |
16 | class main_task: public ccf::user_task
17 | {
18 | void run()
19 | {
20 | int ret;
21 | const char *errmsg;
22 |
23 | ccf::http::post POST(ret, &errmsg, url, data.data(), data.size(), buf, size);
24 | await(POST);
25 |
26 | cerr << "Status Code: " << ret << endl;
27 | if (errmsg)
28 | cerr << "Reason Phrase: " << errmsg << endl;
29 | cerr << "Body Length: " << size << endl;
30 | if (size)
31 | {
32 | buf[size] = '\0';
33 | cout << buf << endl;
34 | }
35 | }
36 | };
37 |
38 | int main(int argc, char *argv[])
39 | {
40 | if (argc < 2)
41 | {
42 | cerr << "Usage: " << argv[0] << " [bufsize=1048576]" << endl;
43 | cerr << " POST data is read from stdin" << endl;
44 | return 1;
45 | }
46 |
47 | url = argv[1];
48 | if (argc > 2)
49 | size = atoi(argv[2]);
50 |
51 | if (size)
52 | {
53 | buf = reinterpret_cast(malloc(size + 1));
54 | if (!buf)
55 | return 2;
56 | }
57 |
58 | stringstream ss;
59 | ss << cin.rdbuf();
60 | data = ss.str();
61 |
62 | ccf::event_task::init(100);
63 | ccf::user_task::init(100);
64 |
65 | //ccf::set_debug(stderr);
66 |
67 | main_task tMain;
68 | ccf::cocoflow(tMain);
69 | return 0;
70 | }
71 |
--------------------------------------------------------------------------------
/extensions/test/test_redis.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "cocoflow.h"
4 | #include "cocoflow-redis.h"
5 |
6 | #define TEST_PORT 6379
7 | #define TEST_KEY "test_key_for_cocoflow_redis"
8 | #define TEST_VAL "test_val_for_cocoflow_redis"
9 | #define TEST_KEY2 "test key for cocoflow redis"
10 | #define TEST_VAL2 "test val for cocoflow redis"
11 |
12 | using namespace std;
13 |
14 | static void show_reply(const redisReply *reply)
15 | {
16 | switch (reply->type)
17 | {
18 | case REDIS_REPLY_STRING:
19 | cout << "str: " << reply->str << endl;
20 | break;
21 | case REDIS_REPLY_ARRAY:
22 | cout << "array: (size=" << reply->elements << ")" << endl;
23 | break;
24 | case REDIS_REPLY_INTEGER:
25 | cout << "int: " << reply->integer << endl;
26 | break;
27 | case REDIS_REPLY_NIL:
28 | cout << "nil" << endl;
29 | break;
30 | case REDIS_REPLY_STATUS:
31 | cout << "status: " << reply->str << endl;
32 | break;
33 | case REDIS_REPLY_ERROR:
34 | cout << "error: " << reply->str << endl;
35 | break;
36 | default:
37 | cout << "bug" << endl;
38 | break;
39 | }
40 | }
41 |
42 | class main_task: public ccf::user_task
43 | {
44 | void run()
45 | {
46 | int ret;
47 | const redisReply *reply;
48 |
49 | ccf::redis r;
50 |
51 | ccf::redis::connect rc(&ret, r, "127.0.0.1", TEST_PORT);
52 | await(rc);
53 | cout << "connect: " << ret << endl;
54 | if (ret)
55 | cout << "errstr: " << r.errstr() << endl;
56 |
57 | ccf::redis::command* rset = new ccf::redis::command(NULL, NULL, r, "SET %s %s", TEST_KEY, TEST_VAL);
58 | start(rset);
59 |
60 | ccf::redis::command rget(&ret, &reply, r, "GET %s", TEST_KEY);
61 | await(rget);
62 | cout << "command(get): " << ret << endl;
63 | if (ret)
64 | cout << "errstr: " << r.errstr() << endl;
65 | else
66 | show_reply(reply);
67 |
68 | const char *argv[] = {
69 | "SET",
70 | TEST_KEY2,
71 | TEST_VAL2
72 | };
73 | ccf::redis::command rset2(&ret, &reply, r, sizeof(argv)/sizeof(argv[0]), argv, NULL);
74 | await(rset2);
75 | cout << "command(set): " << ret << endl;
76 | if (ret)
77 | cout << "errstr: " << r.errstr() << endl;
78 | else
79 | show_reply(reply);
80 |
81 | const char *argv2[] = {
82 | "GET",
83 | TEST_KEY2
84 | };
85 | ccf::redis::command rget2(&ret, &reply, r, sizeof(argv2)/sizeof(argv2[0]), argv2, NULL);
86 | await(rget2);
87 | cout << "command(get): " << ret << endl;
88 | if (ret)
89 | cout << "errstr: " << r.errstr() << endl;
90 | else
91 | show_reply(reply);
92 |
93 | ccf::redis::command rget3(&ret, &reply, r, 1, argv2, NULL); //test error
94 | await(rget3);
95 | cout << "command(get): " << ret << endl;
96 | if (ret)
97 | cout << "errstr: " << r.errstr() << endl;
98 | else
99 | show_reply(reply);
100 | }
101 | };
102 |
103 | int main()
104 | {
105 | ccf::event_task::init(100);
106 | ccf::user_task::init(100);
107 |
108 | //ccf::set_debug(stderr);
109 |
110 | main_task tMain;
111 | ccf::cocoflow(tMain);
112 | return 0;
113 | }
114 |
--------------------------------------------------------------------------------
/extensions/test/test_redis2.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "cocoflow.h"
4 | #include "cocoflow-redis.h"
5 |
6 | #define TEST_PORT 6379
7 | #define TEST_KEY "test_key_for_cocoflow_redis"
8 | #define TEST_VAL "test_val_for_cocoflow_redis"
9 |
10 | using namespace std;
11 |
12 | static void show_reply(const redisReply *reply)
13 | {
14 | switch (reply->type)
15 | {
16 | case REDIS_REPLY_STRING:
17 | cout << "str: " << reply->str << endl;
18 | break;
19 | case REDIS_REPLY_ARRAY:
20 | cout << "array: (size=" << reply->elements << ")" << endl;
21 | break;
22 | case REDIS_REPLY_INTEGER:
23 | cout << "int: " << reply->integer << endl;
24 | break;
25 | case REDIS_REPLY_NIL:
26 | cout << "nil" << endl;
27 | break;
28 | case REDIS_REPLY_STATUS:
29 | cout << "status: " << reply->str << endl;
30 | break;
31 | case REDIS_REPLY_ERROR:
32 | cout << "error: " << reply->str << endl;
33 | break;
34 | default:
35 | cout << "bug" << endl;
36 | break;
37 | }
38 | }
39 |
40 | static void connect_succeed(ccf::redis&, void*)
41 | {
42 | cerr << "connection succeed" << endl;
43 | }
44 |
45 | static void connect_failed(ccf::redis&, void*, ccf::redis::failed_type, const char *message)
46 | {
47 | cerr << message << endl;
48 | }
49 |
50 | class main_task: public ccf::user_task
51 | {
52 | void run()
53 | {
54 | int ret;
55 | const redisReply *reply;
56 |
57 | ccf::redis r;
58 |
59 | r.auto_connect("127.0.0.1", TEST_PORT);
60 | r.set_auto_connect_callback(connect_succeed, connect_failed);
61 |
62 | {
63 | ccf::redis::command rset(&ret, &reply, r, "SET %s %s", TEST_KEY, TEST_VAL);
64 | await(rset);
65 | cout << "command(set): " << ret << endl;
66 | if (ret)
67 | cout << "errstr: " << r.errstr() << endl;
68 | else
69 | show_reply(reply);
70 |
71 | ccf::sleep s(1000);
72 | await(s);
73 | }
74 |
75 | for (;;)
76 | {
77 | ccf::redis::command rget(&ret, &reply, r, "GET %s", TEST_KEY);
78 | await(rget);
79 | cout << "command(get): " << ret << endl;
80 | if (ret)
81 | cout << "errstr: " << r.errstr() << endl;
82 | else
83 | show_reply(reply);
84 |
85 | ccf::sleep s(1000);
86 | await(s);
87 | }
88 | }
89 | };
90 |
91 | int main()
92 | {
93 | ccf::event_task::init(100);
94 | ccf::user_task::init(100);
95 |
96 | //ccf::set_debug(stderr);
97 |
98 | main_task tMain;
99 | ccf::cocoflow(tMain);
100 | return 0;
101 | }
102 |
--------------------------------------------------------------------------------
/extensions/vc/cocoflow-extensions.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 10.00
3 | # Visual Studio 2008
4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libccf-http", "libccf-http.vcproj", "{85BC0E9B-AAA8-4B2D-BDD9-B8C4537D76C0}"
5 | EndProject
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_http_get", "test_http_get.vcproj", "{4CC4CC31-9D25-4173-BA60-EA5073951C83}"
7 | EndProject
8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_http_post", "test_http_post.vcproj", "{4CC4CC31-9D25-4173-BA60-EA5073951C84}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Win32 = Debug|Win32
13 | Debug|Win64 = Debug|Win64
14 | Release|Win32 = Release|Win32
15 | Release|Win64 = Release|Win64
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {85BC0E9B-AAA8-4B2D-BDD9-B8C4537D76C0}.Debug|Win32.ActiveCfg = Debug|Win32
19 | {85BC0E9B-AAA8-4B2D-BDD9-B8C4537D76C0}.Debug|Win32.Build.0 = Debug|Win32
20 | {85BC0E9B-AAA8-4B2D-BDD9-B8C4537D76C0}.Debug|Win64.ActiveCfg = Debug|x64
21 | {85BC0E9B-AAA8-4B2D-BDD9-B8C4537D76C0}.Debug|Win64.Build.0 = Debug|x64
22 | {85BC0E9B-AAA8-4B2D-BDD9-B8C4537D76C0}.Release|Win32.ActiveCfg = Release|Win32
23 | {85BC0E9B-AAA8-4B2D-BDD9-B8C4537D76C0}.Release|Win32.Build.0 = Release|Win32
24 | {85BC0E9B-AAA8-4B2D-BDD9-B8C4537D76C0}.Release|Win64.ActiveCfg = Release|x64
25 | {85BC0E9B-AAA8-4B2D-BDD9-B8C4537D76C0}.Release|Win64.Build.0 = Release|x64
26 | {4CC4CC31-9D25-4173-BA60-EA5073951C83}.Debug|Win32.ActiveCfg = Debug|Win32
27 | {4CC4CC31-9D25-4173-BA60-EA5073951C83}.Debug|Win32.Build.0 = Debug|Win32
28 | {4CC4CC31-9D25-4173-BA60-EA5073951C83}.Debug|Win64.ActiveCfg = Debug|x64
29 | {4CC4CC31-9D25-4173-BA60-EA5073951C83}.Debug|Win64.Build.0 = Debug|x64
30 | {4CC4CC31-9D25-4173-BA60-EA5073951C83}.Release|Win32.ActiveCfg = Release|Win32
31 | {4CC4CC31-9D25-4173-BA60-EA5073951C83}.Release|Win32.Build.0 = Release|Win32
32 | {4CC4CC31-9D25-4173-BA60-EA5073951C83}.Release|Win64.ActiveCfg = Release|x64
33 | {4CC4CC31-9D25-4173-BA60-EA5073951C83}.Release|Win64.Build.0 = Release|x64
34 | {4CC4CC31-9D25-4173-BA60-EA5073951C84}.Debug|Win32.ActiveCfg = Debug|Win32
35 | {4CC4CC31-9D25-4173-BA60-EA5073951C84}.Debug|Win32.Build.0 = Debug|Win32
36 | {4CC4CC31-9D25-4173-BA60-EA5073951C84}.Debug|Win64.ActiveCfg = Debug|x64
37 | {4CC4CC31-9D25-4173-BA60-EA5073951C84}.Debug|Win64.Build.0 = Debug|x64
38 | {4CC4CC31-9D25-4173-BA60-EA5073951C84}.Release|Win32.ActiveCfg = Release|Win32
39 | {4CC4CC31-9D25-4173-BA60-EA5073951C84}.Release|Win32.Build.0 = Release|Win32
40 | {4CC4CC31-9D25-4173-BA60-EA5073951C84}.Release|Win64.ActiveCfg = Release|x64
41 | {4CC4CC31-9D25-4173-BA60-EA5073951C84}.Release|Win64.Build.0 = Release|x64
42 | EndGlobalSection
43 | GlobalSection(SolutionProperties) = preSolution
44 | HideSolutionNode = FALSE
45 | EndGlobalSection
46 | EndGlobal
47 |
--------------------------------------------------------------------------------
/extensions/vc/libccf-http.vcproj:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
15 |
18 |
19 |
20 |
21 |
22 |
29 |
32 |
35 |
38 |
41 |
44 |
57 |
60 |
63 |
66 |
69 |
72 |
75 |
78 |
81 |
84 |
85 |
93 |
96 |
99 |
102 |
105 |
108 |
118 |
121 |
124 |
127 |
130 |
133 |
136 |
139 |
142 |
145 |
146 |
153 |
156 |
159 |
162 |
165 |
169 |
182 |
185 |
188 |
191 |
194 |
197 |
200 |
203 |
206 |
209 |
210 |
218 |
221 |
224 |
227 |
230 |
234 |
244 |
247 |
250 |
253 |
256 |
259 |
262 |
265 |
268 |
271 |
272 |
273 |
274 |
275 |
276 |
281 |
284 |
285 |
286 |
291 |
292 |
297 |
298 |
299 |
300 |
301 |
302 |
--------------------------------------------------------------------------------
/extensions/vcbuild.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | cd %~dp0
4 |
5 | set CCF_PLATFORM=x86
6 | if "%PROCESSOR_ARCHITECTURE%"=="AMD64" set CCF_PLATFORM=x64
7 | if "%1"=="x86" set CCF_PLATFORM=x86
8 | if "%1"=="x64" set CCF_PLATFORM=x64
9 |
10 | set CCF_MS_PLATFORM=WIN32
11 | if "%CCF_PLATFORM%"=="x64" set CCF_MS_PLATFORM=WIN64
12 | set CCF_LIB_PATH=
13 | if "%CCF_PLATFORM%"=="x64" set CCF_LIB_PATH=x64\
14 |
15 | @rem Look for Visual Studio 2013
16 | if not defined VS120COMNTOOLS goto vc-set-2012
17 | if not exist "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2012
18 | call "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" %CCF_PLATFORM%
19 | goto upgrade
20 |
21 | :vc-set-2012
22 | @rem Look for Visual Studio 2012
23 | if not defined VS110COMNTOOLS goto vc-set-2010
24 | if not exist "%VS110COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2010
25 | call "%VS110COMNTOOLS%\..\..\vc\vcvarsall.bat" %CCF_PLATFORM%
26 | goto upgrade
27 |
28 | :vc-set-2010
29 | @rem Look for Visual Studio 2010
30 | if not defined VS100COMNTOOLS goto vc-set-2008
31 | if not exist "%VS100COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2008
32 | call "%VS100COMNTOOLS%\..\..\vc\vcvarsall.bat" %CCF_PLATFORM%
33 | goto upgrade
34 |
35 | :vc-set-2008
36 | @rem Look for Visual Studio 2008
37 | if not defined VS90COMNTOOLS goto vc-set-notfound
38 | if not exist "%VS90COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-notfound
39 | call "%VS90COMNTOOLS%\..\..\vc\vcvarsall.bat" %CCF_PLATFORM%
40 | goto msbuild
41 |
42 | :vc-set-notfound
43 | echo Error: Visual Studio not found
44 | goto exit
45 |
46 | :upgrade
47 | echo Upgrading for Visual Studio ...
48 | devenv /upgrade vc\cocoflow-extensions.sln
49 |
50 | :msbuild
51 | echo Compiling libccf-http ...
52 | msbuild vc\cocoflow-extensions.sln /t:libccf-http /p:Configuration=Debug /p:Platform="%CCF_MS_PLATFORM%" /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo
53 | msbuild vc\cocoflow-extensions.sln /t:libccf-http /p:Configuration=Release /p:Platform="%CCF_MS_PLATFORM%" /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo
54 | xcopy /Y vc\%CCF_LIB_PATH%Debug\libccf-http.lib ..\lib\Debug\ > nul
55 | xcopy /Y vc\%CCF_LIB_PATH%Release\libccf-http.lib ..\lib\Release\ > nul
56 |
57 | echo Compiling test ...
58 | msbuild vc\cocoflow-extensions.sln /t:test_http_get,test_http_post /p:Configuration=Debug /p:Platform="%CCF_MS_PLATFORM%" /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo
59 | msbuild vc\cocoflow-extensions.sln /t:test_http_get,test_http_post /p:Configuration=Release /p:Platform="%CCF_MS_PLATFORM%" /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo
60 |
61 | :exit
62 | pause
63 |
--------------------------------------------------------------------------------
/include/cocoflow-http.h:
--------------------------------------------------------------------------------
1 | #ifndef __COCOFLOW_HTTP_H__
2 | #define __COCOFLOW_HTTP_H__
3 |
4 | #include "cocoflow.h"
5 |
6 | namespace ccf {
7 |
8 | namespace http {
9 |
10 | //retcode
11 | enum {
12 | OK = 200,
13 | unfinished = -1,
14 | err_url_parse = -2,
15 | err_dns_resolve = -3,
16 | err_tcp_connect = -4,
17 | err_send_request = -5,
18 | err_recv_response = -6,
19 | err_response_header_parse = -7,
20 | err_response_body_parse = -8,
21 | err_response_body_too_long = -9,
22 | Continue = 100,
23 | SwitchingProtocols = 101,
24 | Created = 201,
25 | Accepted = 202,
26 | NonAuthoritativeInformation = 203,
27 | NoContent = 204,
28 | ResetContent = 205,
29 | PartialContent = 206,
30 | MultipleChoices = 300,
31 | MovedPermanently = 301,
32 | Found = 302,
33 | SeeOther = 303,
34 | NotModified = 304,
35 | UseProxy = 305,
36 | TemporaryRedirect = 307,
37 | BadRequest = 400,
38 | Unauthorized = 401,
39 | PaymentRequired = 402,
40 | Forbidden = 403,
41 | NotFound = 404,
42 | MethodNotAllowed = 405,
43 | NotAcceptable = 406,
44 | ProxyAuthenticationRequired = 407,
45 | RequestTimeout = 408,
46 | Conflict = 409,
47 | Gone = 410,
48 | LengthRequired = 411,
49 | PreconditionFailed = 412,
50 | RequestEntityTooLarge = 413,
51 | RequestURITooLong = 414,
52 | UnsupportedMediaType = 415,
53 | RequestedRangeNotSatisfiable = 416,
54 | ExpectationFailed = 417,
55 | InternalServerError = 500,
56 | NotImplemented = 501,
57 | BadGateway = 502,
58 | ServiceUnavailable = 503,
59 | GatewayTimeout = 504,
60 | HTTPVersionNotSupported = 505,
61 | };
62 |
63 | class get : public event_task
64 | {
65 | public:
66 | get(int &ret, const char **errmsg, const char *url, void *buf, size_t &len);
67 | virtual ~get();
68 | private:
69 | get(const get&);
70 | get& operator=(const get&);
71 | virtual void run();
72 | virtual void cancel();
73 | int &ret;
74 | const char **errmsg;
75 | const char *url;
76 | void *buf;
77 | size_t &len;
78 | template friend class __client;
79 | };
80 |
81 | class post : public event_task
82 | {
83 | public:
84 | post(int &ret, const char **errmsg, const char *url, const void *pbuf, size_t plen, void *buf, size_t &len);
85 | virtual ~post();
86 | private:
87 | post(const post&);
88 | post& operator=(const post&);
89 | virtual void run();
90 | virtual void cancel();
91 | int &ret;
92 | const char **errmsg;
93 | const char *url;
94 | const void *pbuf;
95 | size_t plen;
96 | void *buf;
97 | size_t &len;
98 | template friend class __client;
99 | };
100 |
101 | } /* end of namespace http */
102 |
103 | } /* end of namespace ccf */
104 |
105 | #endif
106 |
--------------------------------------------------------------------------------
/include/cocoflow-redis.h:
--------------------------------------------------------------------------------
1 | #ifndef __COCOFLOW_REDIS_H__
2 | #define __COCOFLOW_REDIS_H__
3 |
4 | #include "cocoflow.h"
5 |
6 | /* Simplified hiredis.h */
7 | extern "C" {
8 | #ifndef __disable_simplify_hiredis_h__
9 | #define REDIS_UNFINISHED -2
10 | #define REDIS_ERR -1
11 | #define REDIS_OK 0
12 |
13 | #define REDIS_ERR_IO 1 /* Error in read or write */
14 | #define REDIS_ERR_EOF 3 /* End of file */
15 | #define REDIS_ERR_PROTOCOL 4 /* Protocol error */
16 | #define REDIS_ERR_OOM 5 /* Out of memory */
17 | #define REDIS_ERR_OTHER 2 /* Everything else... */
18 |
19 | #define REDIS_REPLY_STRING 1
20 | #define REDIS_REPLY_ARRAY 2
21 | #define REDIS_REPLY_INTEGER 3
22 | #define REDIS_REPLY_NIL 4
23 | #define REDIS_REPLY_STATUS 5
24 | #define REDIS_REPLY_ERROR 6
25 |
26 | typedef struct redisReply {
27 | int type; /* REDIS_REPLY_* */
28 | long long integer; /* The integer when type is REDIS_REPLY_INTEGER */
29 | int len; /* Length of string */
30 | char *str; /* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */
31 | size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */
32 | struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */
33 | } redisReply;
34 | #endif
35 | }
36 |
37 | namespace ccf {
38 |
39 | class redis
40 | {
41 | public:
42 | class connect : public event_task
43 | {
44 | public:
45 | connect(int* ret, redis& handle, const char* ip, int port);
46 | virtual ~connect();
47 | private:
48 | connect(const connect&);
49 | connect& operator=(const connect&);
50 | virtual void run();
51 | virtual void cancel();
52 | int* ret;
53 | redis& handle;
54 | char* ip;
55 | int port;
56 | friend class redis;
57 | };
58 | class command : public event_task
59 | {
60 | public:
61 | command(int* ret, const redisReply** reply, redis& handle, const char* format, ...);
62 | command(int* ret, const redisReply** reply, redis& handle, int argc, const char** argv, const size_t* argvlen = NULL);
63 | virtual ~command();
64 | private:
65 | command(const command&);
66 | command& operator=(const command&);
67 | virtual void run();
68 | virtual void cancel();
69 | int* ret;
70 | const redisReply** reply;
71 | redis& handle;
72 | command** req;
73 | int redis_err;
74 | friend class redis;
75 | };
76 | redis();
77 | ~redis();
78 | const char* errstr();
79 | int auto_connect(const char* ip, int port, int timeout = 2000); //ms
80 | /* set_auto_connect_callback is only for log/monitor */
81 | enum failed_type {
82 | failed_exception = 1, //an error occurred on connecting
83 | failed_disconnect, //connection is closed by peer
84 | failed_timeout //connecting timeout
85 | };
86 | typedef void auto_connect_succeed (redis& handle, void* data);
87 | typedef void auto_connect_failed (redis& handle, void* data, failed_type type, const char *message);
88 | void set_auto_connect_callback(auto_connect_succeed* succeed, auto_connect_failed* failed, void* data = NULL);
89 | private:
90 | void* context;
91 | void* timer; //for connect
92 | int cur_reconnect_interval;
93 | int timeout;
94 | auto_connect_succeed* succeed;
95 | auto_connect_failed* failed;
96 | void* data;
97 | std::string ip;
98 | int port;
99 | bool old_opened; //connect new need close old
100 | int connect_now(bool);
101 | int connect_coming(bool);
102 | static void connect_cb(const struct redisAsyncContext*, int);
103 | static void command_cb(struct redisAsyncContext*, void*, void*);
104 | static void auto_connect_cb(const struct redisAsyncContext*, int);
105 | static void auto_connect_closed_cb(const struct redisAsyncContext*, int);
106 | static void auto_connect_timeout_cb(uv_timer_t*, int);
107 | static void auto_reconnect_next_cb(uv_timer_t*, int);
108 | };
109 |
110 | } /* end of namespace ccf */
111 |
112 | #endif
113 |
--------------------------------------------------------------------------------
/lib/chishaxie:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chishaxie/cocoflow/4c7c0978940b398d972150ee5b0f0ad8530c396f/lib/chishaxie
--------------------------------------------------------------------------------
/src/Makefile:
--------------------------------------------------------------------------------
1 | C_ARGS = -g -Wall -O2
2 | CC = gcc
3 | CX = g++
4 |
5 | UV_VERSION=0.10.27
6 | UV_BUILDTYPE=Release
7 |
8 | LIB = ../lib/libuv.a ../lib/libccf.a
9 |
10 | INC_ARGS = -I../include
11 |
12 | all: $(LIB)
13 |
14 | ../lib/libccf.a: cocoflow.o sleep.o sync.o udp.o tcp.o getaddrinfo.o tools.o max_map_count.o
15 | ar cr $@ $^
16 |
17 | cocoflow.o: cocoflow.cc cocoflow-comm.h max_map_count.h ../include/cocoflow.h uv/uv.h
18 | $(CX) $(C_ARGS) -fPIC -c -o $@ cocoflow.cc $(INC_ARGS)
19 |
20 | sleep.o: sleep.cc cocoflow-comm.h ../include/cocoflow.h uv/uv.h
21 | $(CX) $(C_ARGS) -fPIC -c -o $@ sleep.cc $(INC_ARGS)
22 |
23 | sync.o: sync.cc cocoflow-comm.h ../include/cocoflow.h uv/uv.h
24 | $(CX) $(C_ARGS) -fPIC -c -o $@ sync.cc $(INC_ARGS)
25 |
26 | udp.o: udp.cc cocoflow-comm.h ../include/cocoflow.h uv/uv.h
27 | $(CX) $(C_ARGS) -fPIC -c -o $@ udp.cc $(INC_ARGS)
28 |
29 | tcp.o: tcp.cc cocoflow-comm.h ../include/cocoflow.h uv/uv.h
30 | $(CX) $(C_ARGS) -fPIC -c -o $@ tcp.cc $(INC_ARGS)
31 |
32 | getaddrinfo.o: getaddrinfo.cc cocoflow-comm.h ../include/cocoflow.h uv/uv.h
33 | $(CX) $(C_ARGS) -fPIC -c -o $@ getaddrinfo.cc $(INC_ARGS)
34 |
35 | tools.o: tools.cc cocoflow-comm.h ../include/cocoflow.h uv/uv.h
36 | $(CX) $(C_ARGS) -fPIC -c -o $@ tools.cc $(INC_ARGS)
37 |
38 | max_map_count.o: max_map_count.c max_map_count.h
39 | $(CC) $(C_ARGS) -fPIC -c -o $@ max_map_count.c
40 |
41 | uv/uv.h: ../deps/libuv.a
42 | @mkdir uv; cp -r ../deps/libuv-$(UV_VERSION)/include/* uv/
43 |
44 | ../lib/libuv.a: ../deps/libuv.a
45 | @cp $^ $@
46 |
47 | ../deps/libuv.a: ../deps/libuv-$(UV_VERSION).zip ../deps/gyp.zip
48 | @echo "Dependency analysis ..."
49 | @cd ../deps/; unzip libuv-$(UV_VERSION).zip > /dev/null; unzip gyp.zip > /dev/null; cd libuv-$(UV_VERSION)/; mkdir build; cd build/; mkdir gyp; cd gyp; cp -r ../../../gyp/* ./; cd ../../../../src/
50 | @echo "Compiling libuv ..."
51 | @cd ../deps/libuv-$(UV_VERSION)/; ./gyp_uv.py -f make > /dev/null; cd out/; make BUILDTYPE=$(UV_BUILDTYPE) > /dev/null; cd ../../../src/;
52 | @cp ../deps/libuv-$(UV_VERSION)/out/$(UV_BUILDTYPE)/libuv.a $@
53 | @echo "Compiled libuv"
54 |
55 | .PHONY: clean
56 | clean:
57 | rm -f $(LIB) *.o
58 |
--------------------------------------------------------------------------------
/src/cocoflow-comm.h:
--------------------------------------------------------------------------------
1 | #ifndef __COCOFLOW_COMM_H__
2 | #define __COCOFLOW_COMM_H__
3 |
4 | #include
5 | #include
6 |
7 | #if !defined(_WIN32) && !defined(_WIN64)
8 | # include
9 | # include
10 | # include
11 | #endif
12 |
13 | #if defined(__GNUG__)
14 | # include
15 | #endif
16 |
17 | extern "C" {
18 | #define __disable_simplify_uv_h__
19 | #include "uv/uv.h"
20 | }
21 |
22 | #include "cocoflow.h"
23 |
24 | #define CLASS_TIPS_MAX_LEN 2048
25 |
26 | #if !defined(_MSC_VER)
27 | #define FATAL_ERROR(fmt, args...) \
28 | do { \
29 | fprintf(stderr, "[FATAL]: " fmt "\n", ##args); \
30 | abort(); \
31 | } while(0)
32 | #define LOG_DEBUG(fmt, args...) \
33 | do { \
34 | uint32 ns = uv_hrtime()%1000000000; \
35 | time_t s = time(NULL); \
36 | struct tm date = *localtime(&s); \
37 | fprintf(global_debug_file, "[%02u:%02u:%02u.%09u] [DEBUG]: " fmt "\n", date.tm_hour, date.tm_min, date.tm_sec, ns, ##args); \
38 | } while(0)
39 | #else
40 | #pragma warning(disable:4996)
41 | #pragma warning(disable:4390)
42 | #define FATAL_ERROR(fmt, ...) \
43 | do { \
44 | fprintf(stderr, "[FATAL]: " fmt "\n", __VA_ARGS__); \
45 | abort(); \
46 | } while(0)
47 | #define LOG_DEBUG(fmt, ...) \
48 | do { \
49 | uint32 ns = uv_hrtime()%1000000000; \
50 | time_t s = time(NULL); \
51 | struct tm date = *localtime(&s); \
52 | fprintf(global_debug_file, "[%02u:%02u:%02u.%09u] [DEBUG]: " fmt "\n", date.tm_hour, date.tm_min, date.tm_sec, ns, __VA_ARGS__); \
53 | } while(0)
54 | #endif
55 |
56 | #define CHECK(x) \
57 | do { \
58 | if (ccf_unlikely(!(x))) \
59 | { \
60 | fprintf(stderr, "[ASSERT]: " #x " failed at " __FILE__ ":%u\n", __LINE__); \
61 | abort(); \
62 | } \
63 | } while(0)
64 |
65 | namespace ccf {
66 |
67 | #define task_set_status(task, status) \
68 | do { \
69 | (task)->_info = ((task)->_info & 0xf0) | (status); \
70 | } while(0)
71 | #define task_get_status(task) ((task)->_info & 0x0f)
72 |
73 | #define task_info_uninterruptable 0x10
74 | #define task_info_all_any 0x20
75 |
76 | #define task_set_uninterruptable(task) \
77 | do { \
78 | (task)->_info |= task_info_uninterruptable; \
79 | } while(0)
80 | #define task_is_uninterruptable(task) ((task)->_info & task_info_uninterruptable)
81 |
82 | #define task_set_all_any(task) \
83 | do { \
84 | (task)->_info |= task_info_all_any; \
85 | } while(0)
86 | #define task_is_all_any(task) ((task)->_info & task_info_all_any)
87 |
88 | #if defined(_WIN32) || defined(_WIN64)
89 | typedef LPVOID coroutine;
90 | #define coroutine_by_thread(runtime) \
91 | do { \
92 | (*(runtime)) = ConvertThreadToFiberEx(NULL, FIBER_FLAG_FLOAT_SWITCH); \
93 | CHECK((*(runtime)) != NULL); \
94 | } while(0)
95 | #define coroutine_create(runtime, mem, size, id) \
96 | do { \
97 | (*(runtime)) = CreateFiberEx(size, size, FIBER_FLAG_FLOAT_SWITCH, reinterpret_cast(__task_runtime), reinterpret_cast(id)); \
98 | CHECK((*(runtime)) != NULL); \
99 | } while(0)
100 | #define coroutine_switch(from, to, from_id, to_id) \
101 | do { \
102 | (*from) = GetCurrentFiber(); \
103 | CHECK((*from) != NULL); \
104 | SwitchToFiber(*to); \
105 | } while(0)
106 | #define coroutine_memory_alloc(total_size) reinterpret_cast(0x1000)
107 | #define coroutine_memory_protect(mem, size) ;
108 | #else
109 | typedef ucontext_t coroutine;
110 | #define coroutine_by_thread(runtime) ;
111 | #define coroutine_create(runtime, mem, size, id) \
112 | do { \
113 | CHECK(getcontext(runtime) == 0); \
114 | (runtime)->uc_link = &global_loop_running; \
115 | (runtime)->uc_stack.ss_sp = (mem); \
116 | (runtime)->uc_stack.ss_size = (size); \
117 | makecontext(runtime, reinterpret_cast(__task_runtime), 1, (long)id); \
118 | } while(0)
119 | #define coroutine_switch(from, to, from_id, to_id) \
120 | do { \
121 | if (ccf_unlikely(swapcontext(from, to))) \
122 | FATAL_ERROR("Swap running failed, %u -> %u", from_id, to_id); \
123 | } while(0)
124 | #define coroutine_memory_alloc(total_size) \
125 | mmap(NULL, total_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
126 | #define coroutine_memory_protect(mem, size) \
127 | do { \
128 | CHECK(mprotect(mem, size, PROT_NONE) == 0); \
129 | } while(0)
130 | #endif
131 |
132 | extern coroutine* global_running_manager;
133 | extern coroutine global_loop_running;
134 | extern event_task* global_current_task;
135 | extern bool global_signal_canceled;
136 | extern FILE* global_debug_file;
137 | extern char global_debug_output_src[CLASS_TIPS_MAX_LEN];
138 | extern char global_debug_output_dst[CLASS_TIPS_MAX_LEN];
139 |
140 | inline const char* __task_to_tips(const event_task* et, char* tips, bool show_reuse = false)
141 | {
142 | if (et != NULL)
143 | {
144 | if (!show_reuse || !et->reuse)
145 | {
146 | #if defined(__GNUG__)
147 | size_t len = CLASS_TIPS_MAX_LEN;
148 | abi::__cxa_demangle(typeid(*et).name(), tips, &len, NULL);
149 | #else
150 | strcpy(tips, typeid(*et).name());
151 | #endif
152 | }
153 | else
154 | {
155 | const event_task* reuse = et->reuse;
156 | while (reuse->reuse)
157 | reuse = reuse->reuse;
158 | #if defined(__GNUG__)
159 | char* _t0 = abi::__cxa_demangle(typeid(*et).name(), NULL, NULL, NULL);
160 | char* _t1 = abi::__cxa_demangle(typeid(*reuse).name(), NULL, NULL, NULL);
161 | sprintf(tips, "%s|%s", _t0, _t1);
162 | free(_t0);
163 | free(_t1);
164 | #else
165 | sprintf(tips, "%s|%s", typeid(*et).name(), typeid(*reuse).name());
166 | #endif
167 | }
168 | }
169 | else
170 | strcpy(tips, "???");
171 | return tips;
172 | }
173 |
174 | #define src_to_tips(src) __task_to_tips(src, global_debug_output_src)
175 | #define dst_to_tips(dst) __task_to_tips(dst, global_debug_output_dst)
176 | #define src_to_tips_pro(src) __task_to_tips(src, global_debug_output_src, true)
177 | #define dst_to_tips_pro(dst) __task_to_tips(dst, global_debug_output_dst, true)
178 |
179 | static inline uv_loop_t* loop()
180 | {
181 | static uv_loop_t* __loop = NULL;
182 | if (ccf_unlikely(__loop == NULL))
183 | __loop = uv_default_loop();
184 | return __loop;
185 | }
186 |
187 | #define interrupt_canceled _ic
188 |
189 | struct interrupt_canceled
190 | {
191 | interrupt_canceled(int level) : level(level) {}
192 | const int level;
193 | };
194 |
195 | static inline void swap_running(uint32 cur, uint32 next)
196 | {
197 | coroutine *cur_runing = (cur == EVENT_LOOP_ID) ? (&global_loop_running) : (global_running_manager + cur),
198 | *next_runing = (next == EVENT_LOOP_ID) ? (&global_loop_running) : (global_running_manager + next);
199 | global_current_task = (next == EVENT_LOOP_ID) ? (NULL) : (global_task_manager[next]);
200 | if (ccf_unlikely(global_debug_file))
201 | {
202 | if (cur == EVENT_LOOP_ID)
203 | LOG_DEBUG("[Switch] EventLoop -> %u-<%s>", next, dst_to_tips_pro(global_task_manager[next]));
204 | else if (next == EVENT_LOOP_ID)
205 | LOG_DEBUG("[Switch] %u-<%s> -> EventLoop", cur, src_to_tips_pro(global_task_manager[cur]));
206 | else
207 | LOG_DEBUG("[Switch] %u-<%s> -> %u-<%s>", cur, src_to_tips_pro(global_task_manager[cur]), next, dst_to_tips_pro(global_task_manager[next]));
208 | }
209 | coroutine_switch(cur_runing, next_runing, cur, next);
210 | global_current_task = (cur == EVENT_LOOP_ID) ? (NULL) : (global_task_manager[cur]);
211 | }
212 |
213 | /* false means interrupt by cancel */
214 | inline bool __task_yield(event_task* cur)
215 | {
216 | uint32 source = cur->_unique_id, target = cur->block_to;
217 | cur->block_to = EVENT_LOOP_ID; //switch to block_to only once
218 | swap_running(source, target);
219 | if (global_signal_canceled)
220 | {
221 | global_signal_canceled = false;
222 | if (task_get_status(cur) != canceled) //Indirect
223 | {
224 | task_set_status(cur, canceled);
225 | throw interrupt_canceled(0);
226 | }
227 | else
228 | cur->cancel();
229 | return false;
230 | }
231 | else
232 | return true;
233 | }
234 |
235 | inline void __task_stand(event_task* cur)
236 | {
237 | swap_running(EVENT_LOOP_ID, cur->_unique_id);
238 | }
239 |
240 | /***** uv *****/
241 |
242 | void free_self_close_cb(uv_handle_t* handle);
243 |
244 | /***** sockaddr *****/
245 |
246 | struct sockaddr_in6 sockaddr_in_into_sockaddr_in6(const struct sockaddr_in& addr);
247 | struct sockaddr_in sockaddr_in_outof_sockaddr_in6(const struct sockaddr_in6& addr);
248 |
249 | }
250 |
251 | #endif
252 |
--------------------------------------------------------------------------------
/src/getaddrinfo.cc:
--------------------------------------------------------------------------------
1 | #include "cocoflow-comm.h"
2 |
3 | namespace ccf {
4 |
5 | /***** getaddrinfo *****/
6 |
7 | getaddrinfo::getaddrinfo(int& ret, struct addrinfo** result, const char** errmsg,
8 | const char* node, const char* service, const struct addrinfo* hints)
9 | : req(NULL), ret(ret), result(result), errmsg(errmsg), node(node), service(service), hints(hints)
10 | {
11 | this->ret = -1;
12 | if (this->result)
13 | *this->result = NULL;
14 | if (this->errmsg)
15 | *this->errmsg = NULL;
16 | }
17 |
18 | void getaddrinfo::getaddrinfo_cb(uv_getaddrinfo_t* req, int status, struct addrinfo* result)
19 | {
20 | if (status == 0)
21 | {
22 | if (req->data)
23 | {
24 | reinterpret_cast(req->data)->ret = 0;
25 | if (reinterpret_cast(req->data)->result)
26 | *reinterpret_cast(req->data)->result = result;
27 | else
28 | uv_freeaddrinfo(result);
29 | __task_stand(reinterpret_cast(req->data));
30 | }
31 | else
32 | uv_freeaddrinfo(result);
33 | }
34 | else
35 | {
36 | CHECK(result == NULL);
37 | if (req->data)
38 | {
39 | reinterpret_cast(req->data)->ret = status;
40 | if (reinterpret_cast(req->data)->errmsg)
41 | *reinterpret_cast(req->data)->errmsg = uv_strerror(uv_last_error(loop()));
42 | __task_stand(reinterpret_cast(req->data));
43 | }
44 | }
45 | free(req);
46 | }
47 |
48 | void getaddrinfo::run()
49 | {
50 | this->req = malloc(sizeof(uv_getaddrinfo_t));
51 | CHECK(this->req != NULL);
52 | int status = uv_getaddrinfo(loop(), reinterpret_cast(this->req), getaddrinfo::getaddrinfo_cb,
53 | this->node, this->service, this->hints);
54 | if (status == 0)
55 | {
56 | reinterpret_cast(this->req)->data = this;
57 | (void)__task_yield(this);
58 | }
59 | else
60 | {
61 | this->ret = status;
62 | if (this->errmsg)
63 | *this->errmsg = uv_strerror(uv_last_error(loop()));
64 | free(this->req);
65 | }
66 | }
67 |
68 | void getaddrinfo::cancel()
69 | {
70 | if (this->errmsg)
71 | *this->errmsg = "It was canceled";
72 | (void)uv_cancel(reinterpret_cast(this->req)); //may fail in linux, must fail in win
73 | reinterpret_cast(this->req)->data = NULL;
74 | }
75 |
76 | getaddrinfo::~getaddrinfo()
77 | {
78 | }
79 |
80 | void getaddrinfo::freeaddrinfo(struct addrinfo* result)
81 | {
82 | uv_freeaddrinfo(result);
83 | }
84 |
85 | }
86 |
--------------------------------------------------------------------------------
/src/max_map_count.c:
--------------------------------------------------------------------------------
1 | #define _GNU_SOURCE
2 |
3 | #include
4 |
5 | #include
6 | #include
7 |
8 | #include
9 |
10 | int get_max_map_count()
11 | {
12 | int ret = 0;
13 |
14 | struct __sysctl_args args;
15 | int name[] = {CTL_VM, VM_MAX_MAP_COUNT};
16 | size_t len = sizeof(ret);
17 |
18 | memset(&args, 0, sizeof(args));
19 | args.name = name;
20 | args.nlen = sizeof(name)/sizeof(name[0]);
21 | args.oldval = &ret;
22 | args.oldlenp = &len;
23 |
24 | /* int _sysctl(struct __sysctl_args *args); */
25 | if (syscall(SYS__sysctl, &args) == -1)
26 | return -1;
27 | else
28 | return ret;
29 | }
30 |
--------------------------------------------------------------------------------
/src/max_map_count.h:
--------------------------------------------------------------------------------
1 | #ifndef __MAX_MAP_COUNT_H__
2 | #define __MAX_MAP_COUNT_H__
3 |
4 | #ifdef __cplusplus
5 | extern "C"{
6 | #endif
7 |
8 | int get_max_map_count();
9 |
10 | #ifdef __cplusplus
11 | }
12 | #endif
13 |
14 | #endif
15 |
--------------------------------------------------------------------------------
/src/sleep.cc:
--------------------------------------------------------------------------------
1 | #include "cocoflow-comm.h"
2 |
3 | namespace ccf {
4 |
5 | /***** sleep *****/
6 |
7 | sleep::sleep(uint64 timeout)
8 | : timeout(timeout), timer(NULL)
9 | {
10 | }
11 |
12 | static void sleep_cb(uv_timer_t* req, int status)
13 | {
14 | CHECK(status == 0);
15 | __task_stand(reinterpret_cast(req->data));
16 | }
17 |
18 | void sleep::run()
19 | {
20 | this->timer = malloc(sizeof(uv_timer_t));
21 | CHECK(this->timer != NULL);
22 | CHECK(uv_timer_init(loop(), reinterpret_cast(this->timer)) == 0);
23 | reinterpret_cast(this->timer)->data = this;
24 | CHECK(uv_timer_start(reinterpret_cast(this->timer), sleep_cb, this->timeout, 0) == 0);
25 | if (!__task_yield(this))
26 | return;
27 | uv_close(reinterpret_cast(this->timer), free_self_close_cb);
28 | }
29 |
30 | void sleep::cancel()
31 | {
32 | uv_close(reinterpret_cast(this->timer), free_self_close_cb);
33 | }
34 |
35 | sleep::~sleep()
36 | {
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/sync.cc:
--------------------------------------------------------------------------------
1 | #include "cocoflow-comm.h"
2 |
3 | namespace ccf {
4 |
5 | /***** sync *****/
6 |
7 | sync::sync()
8 | : async(NULL), named(false)
9 | {
10 | }
11 |
12 | sync::sync(long id)
13 | : id(id), async(NULL), named(true)
14 | {
15 | }
16 |
17 | static void sync_cb(uv_async_t* async, int status)
18 | {
19 | CHECK(status == 0);
20 | __task_stand(reinterpret_cast(async->data));
21 | }
22 |
23 | void sync::run()
24 | {
25 | if (this->named)
26 | {
27 | std::pair::iterator, bool> ret = sync::ids.insert(std::pair(this->id, this));
28 | CHECK(ret.second == true);
29 | this->pos = ret.first;
30 | }
31 | this->async = malloc(sizeof(uv_async_t));
32 | CHECK(this->async != NULL);
33 | CHECK(uv_async_init(loop(), reinterpret_cast(this->async), sync_cb) == 0);
34 | reinterpret_cast(this->async)->data = this;
35 | if (!__task_yield(this))
36 | return;
37 | if (this->named)
38 | sync::ids.erase(this->pos);
39 | uv_close(reinterpret_cast(this->async), free_self_close_cb);
40 | this->async = NULL;
41 | }
42 |
43 | void sync::cancel()
44 | {
45 | if (this->named)
46 | sync::ids.erase(this->pos);
47 | uv_close(reinterpret_cast(this->async), free_self_close_cb);
48 | this->async = NULL;
49 | }
50 |
51 | sync::~sync()
52 | {
53 | }
54 |
55 | int sync::notify(sync* obj)
56 | {
57 | if (obj->async)
58 | {
59 | CHECK(uv_async_send(reinterpret_cast(obj->async)) == 0);
60 | return 0;
61 | }
62 | else
63 | return -1;
64 | }
65 |
66 | int sync::notify(long id)
67 | {
68 | std::map::iterator it = sync::ids.find(id);
69 | if (it != sync::ids.end())
70 | {
71 | CHECK(uv_async_send(reinterpret_cast(it->second->async)) == 0);
72 | return 0;
73 | }
74 | else
75 | return -1;
76 | }
77 |
78 | std::map sync::ids;
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/src/tools.cc:
--------------------------------------------------------------------------------
1 | #include "cocoflow-comm.h"
2 |
3 | #if defined(_MSC_VER)
4 | #pragma warning(disable:4748)
5 | #endif
6 |
7 | namespace ccf {
8 |
9 | /***** tools *****/
10 |
11 | union addr_ip {
12 | struct sockaddr_in6 addr6;
13 | struct sockaddr_in addr4;
14 | };
15 |
16 | struct sockaddr_in6 sockaddr_in_into_sockaddr_in6(const struct sockaddr_in& addr)
17 | {
18 | union addr_ip uaddr;
19 | uaddr.addr4 = addr;
20 | return uaddr.addr6;
21 | }
22 |
23 | struct sockaddr_in sockaddr_in_outof_sockaddr_in6(const struct sockaddr_in6& addr)
24 | {
25 | union addr_ip uaddr;
26 | uaddr.addr6 = addr;
27 | return uaddr.addr4;
28 | }
29 |
30 | struct sockaddr_in ip_to_addr(const char* ipv4, int port)
31 | {
32 | return uv_ip4_addr(ipv4, port);
33 | }
34 |
35 | struct sockaddr_in6 ip_to_addr6(const char* ipv6, int port)
36 | {
37 | return uv_ip6_addr(ipv6, port);
38 | }
39 |
40 | std::string ip_to_str(const struct sockaddr* addr)
41 | {
42 | if (addr->sa_family == AF_INET)
43 | return ip_to_str(*reinterpret_cast(addr));
44 | else if (addr->sa_family == AF_INET6)
45 | return ip_to_str(*reinterpret_cast(addr));
46 | else
47 | return std::string("Not IP Address");
48 | }
49 |
50 | std::string ip_to_str(const struct sockaddr_in& addr)
51 | {
52 | char str[112], tmp[16];
53 | if (uv_ip4_name(const_cast(&addr), str, sizeof(str)) == 0)
54 | {
55 | sprintf(tmp, ":%u", ntohs(addr.sin_port));
56 | strcat(str, tmp);
57 | }
58 | else
59 | strcpy(str, "Illegal IPv4 Address");
60 | return std::string(str);
61 | }
62 |
63 | std::string ip_to_str(const struct sockaddr_in6& addr)
64 | {
65 | char str[112], tmp[16];
66 | if (uv_ip6_name(const_cast(&addr), str+1, sizeof(str)-1) == 0)
67 | {
68 | str[0] = '[';
69 | sprintf(tmp, "]:%u", ntohs(addr.sin6_port));
70 | strcat(str, tmp);
71 | }
72 | else
73 | strcpy(str, "Illegal IPv6 Address");
74 | return std::string(str);
75 | }
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/test/Makefile:
--------------------------------------------------------------------------------
1 | C_ARGS = -g -Wall -O2
2 | CX = g++
3 | NO_CHECK = -Ddisable_check_seq_type
4 |
5 | LIB = ../lib/libuv.a ../lib/libccf.a
6 | BIN = test_primitive test_sleep test_udp test_udp2 test_udp3 test_tcp test_tcp2 test_tcp3 unexpected_tcp_timing test_getaddrinfo benchmark_sleep benchmark_udp benchmark_udp2 benchmark_udp2_without_check_seq_type benchmark_tcp benchmark_tcp_without_check_seq_type
7 |
8 | LIB_ARGS = -L../lib -lccf -luv -lpthread -lrt
9 | INC_ARGS = -I../include
10 |
11 | all: $(BIN)
12 |
13 | $(LIB):
14 | make -C ../src/
15 |
16 | test_primitive: test_primitive.cc $(LIB)
17 | $(CX) $(C_ARGS) -o $@ test_primitive.cc $(LIB_ARGS) $(INC_ARGS)
18 |
19 | test_sleep: test_sleep.cc $(LIB)
20 | $(CX) $(C_ARGS) -o $@ test_sleep.cc $(LIB_ARGS) $(INC_ARGS)
21 |
22 | test_udp: test_udp.cc $(LIB)
23 | $(CX) $(C_ARGS) -o $@ test_udp.cc $(LIB_ARGS) $(INC_ARGS)
24 |
25 | test_udp2: test_udp2.cc $(LIB)
26 | $(CX) $(C_ARGS) -o $@ test_udp2.cc $(LIB_ARGS) $(INC_ARGS)
27 |
28 | test_udp3: test_udp3.cc $(LIB)
29 | $(CX) $(C_ARGS) -o $@ test_udp3.cc $(LIB_ARGS) $(INC_ARGS)
30 |
31 | test_tcp: test_tcp.cc $(LIB)
32 | $(CX) $(C_ARGS) -o $@ test_tcp.cc $(LIB_ARGS) $(INC_ARGS)
33 |
34 | test_tcp2: test_tcp2.cc $(LIB)
35 | $(CX) $(C_ARGS) -o $@ test_tcp2.cc $(LIB_ARGS) $(INC_ARGS)
36 |
37 | test_tcp3: test_tcp3.cc $(LIB)
38 | $(CX) $(C_ARGS) -o $@ test_tcp3.cc $(LIB_ARGS) $(INC_ARGS)
39 |
40 | unexpected_tcp_timing: unexpected_tcp_timing.cc $(LIB)
41 | $(CX) $(C_ARGS) -o $@ unexpected_tcp_timing.cc $(LIB_ARGS) $(INC_ARGS)
42 |
43 | test_getaddrinfo: test_getaddrinfo.cc $(LIB)
44 | $(CX) $(C_ARGS) -o $@ test_getaddrinfo.cc $(LIB_ARGS) $(INC_ARGS)
45 |
46 | benchmark_sleep: benchmark_sleep.cc $(LIB)
47 | $(CX) $(C_ARGS) -o $@ benchmark_sleep.cc $(LIB_ARGS) $(INC_ARGS)
48 |
49 | benchmark_udp: benchmark_udp.cc $(LIB)
50 | $(CX) $(C_ARGS) -o $@ benchmark_udp.cc $(LIB_ARGS) $(INC_ARGS)
51 |
52 | benchmark_udp2: benchmark_udp2.cc $(LIB)
53 | $(CX) $(C_ARGS) -o $@ benchmark_udp2.cc $(LIB_ARGS) $(INC_ARGS)
54 |
55 | benchmark_udp2_without_check_seq_type: benchmark_udp2.cc $(LIB)
56 | $(CX) $(C_ARGS) -o $@ benchmark_udp2.cc $(LIB_ARGS) $(INC_ARGS) $(NO_CHECK)
57 |
58 | benchmark_tcp: benchmark_tcp.cc $(LIB)
59 | $(CX) $(C_ARGS) -o $@ benchmark_tcp.cc $(LIB_ARGS) $(INC_ARGS)
60 |
61 | benchmark_tcp_without_check_seq_type: benchmark_tcp.cc $(LIB)
62 | $(CX) $(C_ARGS) -o $@ benchmark_tcp.cc $(LIB_ARGS) $(INC_ARGS) $(NO_CHECK)
63 |
64 | .PHONY: clean
65 | clean:
66 | rm -f $(BIN)
67 |
68 | .PHONY: test all_test
69 |
70 | test: test_primitive
71 | @(./test_primitive && echo 'Succeed!') || echo 'Failed!'
72 |
73 | all_test: $(BIN)
74 | @echo 'test primitive'
75 | @(./test_primitive && echo 'Succeed') || echo 'Failed'
76 | @echo 'test sleep'
77 | @(./test_sleep > /dev/null && echo 'Succeed') || echo 'Failed'
78 | @echo 'test udp [3]'
79 | @(./test_udp > /dev/null && echo 'Succeed') || echo 'Failed'
80 | @(./test_udp2 > /dev/null && echo 'Succeed') || echo 'Failed'
81 | @(./test_udp3 > /dev/null && echo 'Succeed') || echo 'Failed'
82 | @echo 'test tcp [3]'
83 | @(./test_tcp > /dev/null && echo 'Succeed') || echo 'Failed'
84 | @(./test_tcp2 > /dev/null && echo 'Succeed') || echo 'Failed'
85 | @(./test_tcp3 > /dev/null && echo 'Succeed') || echo 'Failed'
86 | @echo 'test tcp timing'
87 | @(./unexpected_tcp_timing > /dev/null && echo 'Succeed') || echo 'Failed'
88 | @echo 'test getaddrinfo'
89 | @(./test_getaddrinfo > /dev/null && echo 'Succeed') || echo 'Failed'
90 | @echo 'benchmark sleep'
91 | @(./benchmark_sleep > /dev/null && echo 'Succeed') || echo 'Failed'
92 | @echo 'benchmark udp'
93 | @(./benchmark_udp2 > /dev/null && echo 'Succeed') || echo 'Failed'
94 | @echo 'benchmark udp (without check seq type)'
95 | @(./benchmark_udp2_without_check_seq_type > /dev/null && echo 'Succeed') || echo 'Failed'
96 | @echo 'benchmark tcp'
97 | @(./benchmark_tcp > /dev/null && echo 'Succeed') || echo 'Failed'
98 | @echo 'benchmark tcp (without check seq type)'
99 | @(./benchmark_tcp_without_check_seq_type > /dev/null && echo 'Succeed') || echo 'Failed'
100 |
--------------------------------------------------------------------------------
/test/benchmark_sleep.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include
5 |
6 | #include "cocoflow.h"
7 |
8 | using namespace std;
9 |
10 | #define TEST_TIMES 1000
11 | #define TEST_NUM 1000
12 |
13 | #define ASSERT(x) \
14 | do { \
15 | if (!(x)) \
16 | { \
17 | fprintf(stderr, "[ASSERT]: " #x " failed at " __FILE__ ":%u\n", __LINE__); \
18 | abort(); \
19 | } \
20 | } while(0)
21 |
22 | static clock_t time_bgn, time_cut, time_end;
23 |
24 | typedef ccf::task<15> test_task;
25 |
26 | class sleep_task: public test_task
27 | {
28 | void run()
29 | {
30 | for (int i=0; istatus() == ccf::ready);
46 | ccf::start(s);
47 | }
48 | }
49 | };
50 |
51 | int main()
52 | {
53 | time_bgn = clock();
54 |
55 | ccf::event_task::init(1);
56 | test_task::init(TEST_NUM + 1);
57 | main_task tMain;
58 |
59 | time_cut = clock();
60 |
61 | ccf::cocoflow(tMain);
62 |
63 | time_end = clock();
64 |
65 | cout << "Init: " << (time_cut - time_bgn) << endl;
66 | cout << "Proc: " << (time_end - time_cut) << endl;
67 | cout << "Total: " << (time_end - time_bgn) << endl;
68 |
69 | return 0;
70 | }
71 |
--------------------------------------------------------------------------------
/test/benchmark_tcp.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include
5 |
6 | #include "cocoflow.h"
7 |
8 | #include "simple_rand.h"
9 |
10 | using namespace std;
11 |
12 | #define TEST_PORT 31005
13 | #ifdef _WIN32
14 | #define TEST_TIMES 300 //lite
15 | #else
16 | #define TEST_TIMES 6000
17 | #endif
18 |
19 | #ifdef _MSC_VER
20 | #define ENSURE_TIMING 1 //Avoid unexpected tcp timing in Win
21 | #endif
22 |
23 | #define ASSERT(x) \
24 | do { \
25 | if (!(x)) \
26 | { \
27 | fprintf(stderr, "[ASSERT]: " #x " failed at " __FILE__ ":%u\n", __LINE__); \
28 | abort(); \
29 | } \
30 | } while(0)
31 |
32 | static void my_pkg_seq_unrecv(const void*, size_t, const ccf::uint32&)
33 | {
34 | ASSERT(0);
35 | }
36 |
37 | static void my_pkg_seq_failed(const void*, size_t, int)
38 | {
39 | ASSERT(0);
40 | }
41 |
42 | static clock_t time_bgn, time_cut, time_end;
43 |
44 | typedef ccf::task<15> test_task;
45 |
46 | size_t get_len_from_header(const void* buf, size_t size)
47 | {
48 | if (size < sizeof(ccf::uint32))
49 | return 0;
50 | const ccf::uint32 *len = (const ccf::uint32 *)buf;
51 | return *len;
52 | }
53 |
54 | int get_seq_from_buf(const void* buf, size_t size, ccf::uint32* seq)
55 | {
56 | if (size < sizeof(ccf::uint32) + sizeof(ccf::uint32))
57 | return -1;
58 | *seq = ntohl(*(((ccf::uint32*)buf) + 1));
59 | return 0;
60 | }
61 |
62 | class echo_task: public test_task
63 | {
64 | static int times;
65 | static ccf::tcp::connected tc;
66 | void run()
67 | {
68 | int ret;
69 | char buf[1024];
70 | size_t len = sizeof(buf);
71 | ccf::tcp::recv tr(ret, echo_task::tc, buf, len);
72 | await(tr);
73 | ASSERT(ret == ccf::tcp::success);
74 | if (++echo_task::times < TEST_TIMES)
75 | {
76 | echo_task* echo = new echo_task();
77 | ASSERT(echo->status() == ccf::ready);
78 | ccf::start(echo);
79 | }
80 | ccf::tcp::send ts(ret, echo_task::tc, buf, len);
81 | await(ts);
82 | ASSERT(ret == ccf::tcp::success);
83 | }
84 | friend class accept_task;
85 | public:
86 | static void init()
87 | {
88 | ASSERT(echo_task::tc.bind(sizeof(ccf::uint32), 1024, get_len_from_header, get_seq_from_buf, my_pkg_seq_unrecv, my_pkg_seq_failed) == 0);
89 | }
90 | };
91 |
92 | int echo_task::times = 0;
93 | ccf::tcp::connected echo_task::tc;
94 |
95 | class accept_task: public test_task
96 | {
97 | static ccf::tcp::listening tl;
98 | void run()
99 | {
100 | int ret;
101 | ASSERT(accept_task::tl.bind(ccf::ip_to_addr("0.0.0.0", TEST_PORT)) == 0);
102 | ccf::tcp::accept ta(ret, accept_task::tl, echo_task::tc);
103 | await(ta);
104 | ASSERT(ret == ccf::tcp::success);
105 | echo_task::init();
106 | ccf::start(new echo_task());
107 | }
108 | };
109 |
110 | ccf::tcp::listening accept_task::tl(1);
111 |
112 | class seq_task: public test_task
113 | {
114 | static int times;
115 | static ccf::tcp::connected tc;
116 | ccf::uint32 seq;
117 | void run()
118 | {
119 | int ret0, ret1;
120 | char buf_in[1024], buf_out[1024];
121 | ccf::uint32 *plen = (ccf::uint32 *)buf_out;
122 | ccf::uint32 *pseq = ((ccf::uint32 *)buf_out) + 1;
123 | *plen = simple_rand()%128 + 8;
124 | *pseq = htonl(this->seq);
125 | size_t len = sizeof(buf_in);
126 | #ifndef ENSURE_TIMING
127 | ccf::tcp::send ts(ret0, seq_task::tc, buf_out, *plen);
128 | await(ts);
129 | ASSERT(ret0 == ccf::tcp::success);
130 | ccf::tcp::recv_by_seq_u32 tr(ret1, seq_task::tc, buf_in, len, this->seq);
131 | await(tr);
132 | ASSERT(ret1 == ccf::tcp::success);
133 | #else
134 | ccf::tcp::send ts(ret0, seq_task::tc, buf_out, *plen);
135 | ccf::tcp::recv_by_seq_u32 tr(ret1, seq_task::tc, buf_in, len, this->seq);
136 | ccf::all_of all(ts, tr);
137 | await(all);
138 | ASSERT(ret0 == ccf::tcp::success);
139 | ASSERT(ret1 == ccf::tcp::success);
140 | #endif
141 | if (++seq_task::times == TEST_TIMES)
142 | {
143 | time_end = clock();
144 | cout << "Init: " << (time_cut - time_bgn) << endl;
145 | cout << "Proc: " << (time_end - time_cut) << endl;
146 | cout << "Total: " << (time_end - time_bgn) << endl;
147 | exit(0);
148 | }
149 | }
150 | public:
151 | static void init()
152 | {
153 | int ret;
154 | ccf::tcp::connect c(ret, seq_task::tc, ccf::ip_to_addr("127.0.0.1", TEST_PORT));
155 | await(c);
156 | ASSERT(ret == ccf::tcp::success);
157 | ASSERT(seq_task::tc.bind(sizeof(ccf::uint32), 1024, get_len_from_header, get_seq_from_buf, my_pkg_seq_unrecv, my_pkg_seq_failed) == 0);
158 | }
159 | seq_task(ccf::uint32 seq) : seq(seq) {}
160 | };
161 |
162 | int seq_task::times = 0;
163 | ccf::tcp::connected seq_task::tc;
164 |
165 | class main_task: public test_task
166 | {
167 | void run()
168 | {
169 | ccf::start(new accept_task());
170 | seq_task::init();
171 | for (int i=0; istatus() == ccf::ready);
175 | ccf::start(seq);
176 | }
177 | }
178 | };
179 |
180 | int main()
181 | {
182 | time_bgn = clock();
183 |
184 | #ifndef ENSURE_TIMING
185 | ccf::event_task::init(1);
186 | #else
187 | ccf::event_task::init(TEST_TIMES * 2);
188 | #endif
189 | test_task::init(TEST_TIMES * 2 + 1);
190 | main_task tMain;
191 |
192 | time_cut = clock();
193 |
194 | ccf::cocoflow(tMain);
195 |
196 | return 0;
197 | }
198 |
--------------------------------------------------------------------------------
/test/benchmark_udp.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include
5 |
6 | #include "cocoflow.h"
7 |
8 | using namespace std;
9 |
10 | #define TEST_PORT 30917
11 | #ifdef _WIN32
12 | #define TEST_TIMES 1000 //lite
13 | #else
14 | #define TEST_TIMES 10000
15 | #endif
16 |
17 | #define ASSERT(x) \
18 | do { \
19 | if (!(x)) \
20 | { \
21 | fprintf(stderr, "[ASSERT]: " #x " failed at " __FILE__ ":%u\n", __LINE__); \
22 | abort(); \
23 | } \
24 | } while(0)
25 |
26 | static void my_pkg_seq_unrecv(const void*, size_t, const ccf::uint32&)
27 | {
28 | ASSERT(0);
29 | }
30 |
31 | static void my_pkg_seq_failed(const void*, size_t, int)
32 | {
33 | ASSERT(0);
34 | }
35 |
36 | static clock_t time_bgn, time_cut, time_end;
37 | static int sleep_time = 2;
38 |
39 | typedef ccf::task<15> test_task;
40 |
41 | class echo_task: public test_task
42 | {
43 | static int times;
44 | static ccf::udp u;
45 | void run()
46 | {
47 | char buf[4096];
48 | struct sockaddr_in peer;
49 | size_t len = sizeof(buf);
50 | ccf::udp::recv ur(echo_task::u, buf, len);
51 | await(ur);
52 | ASSERT(ur.peer_type() == AF_INET);
53 | peer = ur.peer_addr_ipv4();
54 | if (++echo_task::times < TEST_TIMES)
55 | {
56 | echo_task* echo = new echo_task();
57 | ASSERT(echo->status() == ccf::ready);
58 | ccf::start(echo);
59 | }
60 | ccf::udp::send us(echo_task::u, peer, buf, len);
61 | await(us);
62 | }
63 | public:
64 | static void init()
65 | {
66 | ASSERT(u.bind(ccf::ip_to_addr("0.0.0.0", TEST_PORT)) == 0);
67 | }
68 | };
69 |
70 | int echo_task::times = 0;
71 | ccf::udp echo_task::u;
72 |
73 | int get_seq_from_buf(const void* buf, size_t size, ccf::uint32* seq)
74 | {
75 | if (size < sizeof(ccf::uint32))
76 | return -1;
77 | *seq = ntohl(*(ccf::uint32*)buf);
78 | return 0;
79 | }
80 |
81 | class seq_task: public test_task
82 | {
83 | static int times;
84 | static ccf::udp u;
85 | static struct sockaddr_in target;
86 | ccf::uint32 seq;
87 | void run()
88 | {
89 | char buf[4096];
90 | ccf::uint32 *pos = (ccf::uint32 *)buf;
91 | *pos = htonl(this->seq);
92 | ccf::udp::send us(seq_task::u, seq_task::target, buf, sizeof(ccf::uint32));
93 | await(us);
94 | size_t len = sizeof(buf);
95 | ccf::udp::recv_by_seq_u32 ur(seq_task::u, buf, len, this->seq);
96 | await(ur);
97 | if (++seq_task::times == TEST_TIMES)
98 | {
99 | time_end = clock();
100 | cout << "Init: " << (time_cut - time_bgn) << endl;
101 | cout << "Proc: " << (time_end - time_cut) << endl;
102 | cout << "Total: " << (time_end - time_bgn) << endl;
103 | exit(0);
104 | }
105 | }
106 | public:
107 | static void init()
108 | {
109 | seq_task::target = ccf::ip_to_addr("127.0.0.1", TEST_PORT);
110 | ASSERT(seq_task::u.bind(get_seq_from_buf, my_pkg_seq_unrecv, my_pkg_seq_failed) == 0);
111 | }
112 | seq_task(ccf::uint32 seq) : seq(seq) {}
113 | };
114 |
115 | int seq_task::times = 0;
116 | ccf::udp seq_task::u;
117 | struct sockaddr_in seq_task::target;
118 |
119 | class main_task: public test_task
120 | {
121 | void run()
122 | {
123 | echo_task::init();
124 | seq_task::init();
125 | ccf::start(new echo_task());
126 | for (int i=0; istatus() == ccf::ready);
135 | ccf::start(seq);
136 | }
137 | }
138 | };
139 |
140 | int main(int argc, char* argv[])
141 | {
142 | if (argc > 1)
143 | sleep_time = atoi(argv[1]);
144 |
145 | time_bgn = clock();
146 |
147 | ccf::event_task::init(1);
148 | test_task::init(TEST_TIMES + 101);
149 | main_task tMain;
150 |
151 | time_cut = clock();
152 |
153 | ccf::cocoflow(tMain);
154 |
155 | return 0;
156 | }
157 |
--------------------------------------------------------------------------------
/test/benchmark_udp2.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include
5 |
6 | #include "cocoflow.h"
7 |
8 | using namespace std;
9 |
10 | #define TEST_PORT 30917
11 | #ifdef _WIN32
12 | #define TEST_TIMES 1000 //lite
13 | #else
14 | #define TEST_TIMES 10000
15 | #endif
16 |
17 | #define ASSERT(x) \
18 | do { \
19 | if (!(x)) \
20 | { \
21 | fprintf(stderr, "[ASSERT]: " #x " failed at " __FILE__ ":%u\n", __LINE__); \
22 | abort(); \
23 | } \
24 | } while(0)
25 |
26 | static void my_pkg_seq_unrecv(const void*, size_t, const ccf::uint32&)
27 | {
28 | ASSERT(0);
29 | }
30 |
31 | static void my_pkg_seq_failed(const void*, size_t, int)
32 | {
33 | ASSERT(0);
34 | }
35 |
36 | static clock_t time_bgn, time_cut, time_end;
37 |
38 | typedef ccf::task<15> test_task;
39 |
40 | class echo_task: public test_task
41 | {
42 | static int times;
43 | static ccf::udp u;
44 | void run()
45 | {
46 | char buf[4096];
47 | struct sockaddr_in peer;
48 | size_t len = sizeof(buf);
49 | ccf::udp::recv ur(echo_task::u, buf, len);
50 | await(ur);
51 | ASSERT(ur.peer_type() == AF_INET);
52 | peer = ur.peer_addr_ipv4();
53 | if (++echo_task::times < TEST_TIMES)
54 | {
55 | echo_task* echo = new echo_task();
56 | ASSERT(echo->status() == ccf::ready);
57 | ccf::start(echo);
58 | }
59 | ccf::udp::send us(echo_task::u, peer, buf, len);
60 | await(us);
61 | }
62 | public:
63 | static void init()
64 | {
65 | ASSERT(u.bind(ccf::ip_to_addr("0.0.0.0", TEST_PORT)) == 0);
66 | }
67 | };
68 |
69 | int echo_task::times = 0;
70 | ccf::udp echo_task::u;
71 |
72 | int get_seq_from_buf(const void* buf, size_t size, ccf::uint32* seq)
73 | {
74 | if (size < sizeof(ccf::uint32))
75 | return -1;
76 | *seq = ntohl(*(ccf::uint32*)buf);
77 | return 0;
78 | }
79 |
80 | class seq_task: public test_task
81 | {
82 | static int times;
83 | static ccf::udp u;
84 | static struct sockaddr_in target;
85 | ccf::uint32 seq;
86 | void run()
87 | {
88 | char buf[4096];
89 | ccf::uint32 *pos = (ccf::uint32 *)buf;
90 | *pos = htonl(this->seq);
91 | ccf::udp::send us(seq_task::u, seq_task::target, buf, sizeof(ccf::uint32));
92 | await(us);
93 | size_t len = sizeof(buf);
94 | ccf::udp::recv_by_seq_u32 ur(seq_task::u, buf, len, this->seq);
95 | await(ur);
96 | if (++seq_task::times == TEST_TIMES)
97 | {
98 | time_end = clock();
99 | cout << "Init: " << (time_cut - time_bgn) << endl;
100 | cout << "Proc: " << (time_end - time_cut) << endl;
101 | cout << "Total: " << (time_end - time_bgn) << endl;
102 | exit(0);
103 | }
104 | if ((seq_task::times+1)%100 == 99)
105 | ccf::sync::notify(0l);
106 | }
107 | public:
108 | static void init()
109 | {
110 | seq_task::target = ccf::ip_to_addr("127.0.0.1", TEST_PORT);
111 | ASSERT(seq_task::u.bind(get_seq_from_buf, my_pkg_seq_unrecv, my_pkg_seq_failed) == 0);
112 | }
113 | seq_task(ccf::uint32 seq) : seq(seq) {}
114 | };
115 |
116 | int seq_task::times = 0;
117 | ccf::udp seq_task::u;
118 | struct sockaddr_in seq_task::target;
119 |
120 | class main_task: public test_task
121 | {
122 | void run()
123 | {
124 | echo_task::init();
125 | seq_task::init();
126 | ccf::start(new echo_task());
127 | for (int i=0; istatus() == ccf::ready);
136 | ccf::start(seq);
137 | }
138 | }
139 | };
140 |
141 | int main()
142 | {
143 | time_bgn = clock();
144 |
145 | ccf::event_task::init(1);
146 | test_task::init(TEST_TIMES + 101);
147 | main_task tMain;
148 |
149 | time_cut = clock();
150 |
151 | ccf::cocoflow(tMain);
152 |
153 | return 0;
154 | }
155 |
--------------------------------------------------------------------------------
/test/simple_rand.h:
--------------------------------------------------------------------------------
1 | #ifndef __SIMPLE_RAMD_H__
2 | #define __SIMPLE_RAMD_H__
3 |
4 | /* Just to remove the platform differences */
5 | static int simple_rand()
6 | {
7 | static unsigned long seed = 404264294;
8 | return (((seed = seed * 214013L + 2531011L) >> 16) & 0x7fff);
9 | }
10 |
11 | #endif
12 |
--------------------------------------------------------------------------------
/test/test_getaddrinfo.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "cocoflow.h"
4 |
5 | using namespace std;
6 |
7 | void show(int ret, struct addrinfo *result, const char *errmsg)
8 | {
9 | if (ret)
10 | {
11 | if (errmsg)
12 | cout << "getaddrinfo: " << ret << " " << errmsg << endl;
13 | else
14 | cout << "getaddrinfo: " << ret << endl;
15 | }
16 | else
17 | {
18 | cout << "getaddrinfo:" << endl;
19 | struct addrinfo *cur = result;
20 | while (cur)
21 | {
22 | cout << " " << ccf::ip_to_str(cur->ai_addr) << endl;
23 | cur = cur->ai_next;
24 | }
25 | ccf::getaddrinfo::freeaddrinfo(result);
26 | }
27 | }
28 |
29 | class main_task: public ccf::user_task
30 | {
31 | void run()
32 | {
33 | int ret;
34 | struct addrinfo *result;
35 | const char *errmsg;
36 |
37 | ccf::getaddrinfo server(ret, &result, &errmsg, NULL, "ssh");
38 | await(server);
39 | show(ret, result, errmsg);
40 |
41 | ccf::getaddrinfo dns(ret, &result, &errmsg, "localhost", NULL);
42 | await(dns);
43 | show(ret, result, errmsg);
44 |
45 | ccf::getaddrinfo dns2(ret, &result, &errmsg, "www.qq.com", NULL);
46 | await(dns2);
47 | show(ret, result, errmsg);
48 |
49 | ccf::getaddrinfo dns3(ret, &result, &errmsg, "127.0.0.1", NULL);
50 | await(dns3);
51 | show(ret, result, errmsg);
52 |
53 | ccf::getaddrinfo none(ret, &result, &errmsg, NULL, NULL);
54 | await(none);
55 | show(ret, result, errmsg);
56 |
57 | ccf::getaddrinfo dns4(ret, &result, &errmsg, "www.qq.com", NULL);
58 | ccf::sleep s(0);
59 | ccf::any_of any(dns4, s);
60 | await(any);
61 | show(ret, result, errmsg);
62 | }
63 | };
64 |
65 | int main()
66 | {
67 | ccf::event_task::init(100);
68 | ccf::user_task::init(100);
69 |
70 | //ccf::set_debug(stderr);
71 |
72 | main_task tMain;
73 | ccf::cocoflow(tMain);
74 | return 0;
75 | }
76 |
--------------------------------------------------------------------------------
/test/test_sleep.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "cocoflow.h"
4 |
5 | using namespace std;
6 |
7 | class test_task: public ccf::user_task
8 | {
9 | int id;
10 | void run()
11 | {
12 | cout << this->id << " await sleep(3000)" << endl;
13 | ccf::sleep s1(1000), s2(2000);
14 | await(s1);
15 | await(s2);
16 | cout << this->id << " await End" << endl;
17 | }
18 | public:
19 | test_task(int id):id(id){}
20 | };
21 |
22 | class main_task: public ccf::user_task
23 | {
24 | void run()
25 | {
26 | cout << "await test_task(0:new)" << endl;
27 | test_task tt(0);
28 | await(tt);
29 | cout << "start test_task(0:end, 1:new)" << endl;
30 | ccf::start(new test_task(1));
31 | cout << "start test_task(1:end, 2:new)" << endl;
32 | ccf::start(new test_task(2));
33 | cout << "start test_task(2:end, 3:new)" << endl;
34 | ccf::start(new test_task(3));
35 | cout << "start test_task(3:end, 4:new)" << endl;
36 | ccf::start(new test_task(4));
37 | cout << "start test_task(4:end)" << endl;
38 | }
39 | };
40 |
41 | int main()
42 | {
43 | ccf::event_task::init(100);
44 | ccf::user_task::init(100);
45 |
46 | //ccf::set_debug(stderr);
47 |
48 | main_task tMain;
49 | ccf::cocoflow(tMain);
50 | return 0;
51 | }
52 |
--------------------------------------------------------------------------------
/test/test_tcp.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include
4 |
5 | #include "cocoflow.h"
6 |
7 | #include "simple_rand.h"
8 |
9 | using namespace std;
10 |
11 | #define TEST_PORT 31005
12 | #define TEST_TIMES 10
13 | #define TEST_LEN 16
14 |
15 | #define ASSERT(x) \
16 | do { \
17 | if (!(x)) \
18 | { \
19 | fprintf(stderr, "[ASSERT]: " #x " failed at " __FILE__ ":%u\n", __LINE__); \
20 | abort(); \
21 | } \
22 | } while(0)
23 |
24 | class recv_task: public ccf::user_task
25 | {
26 | void run()
27 | {
28 | int ret;
29 | ccf::tcp::listening tl(1);
30 | ASSERT(tl.bind(ccf::ip_to_addr("0.0.0.0", TEST_PORT)) == 0);
31 | ccf::tcp::connected tc;
32 | ccf::tcp::accept ta(ret, tl, tc);
33 | await(ta);
34 | ASSERT(ret == ccf::tcp::success);
35 | size_t total_len = 0;
36 | for (;;)
37 | {
38 | char buf[64];
39 | ccf::sleep s(simple_rand()%5000);
40 | await(s);
41 | size_t len = sizeof(buf);
42 | ccf::tcp::recv tr(ret, tc, buf, len);
43 | await(tr);
44 | ASSERT(ret == ccf::tcp::success);
45 | cout << "server recv " << len << endl;
46 | total_len += len;
47 | if (total_len == TEST_TIMES * TEST_LEN)
48 | break;
49 | }
50 | }
51 | };
52 |
53 | class send_task: public ccf::user_task
54 | {
55 | void run()
56 | {
57 | int ret;
58 | ccf::tcp::connected tc;
59 | ccf::tcp::connect c(ret, tc, ccf::ip_to_addr("127.0.0.1", TEST_PORT));
60 | await(c);
61 | ASSERT(ret == ccf::tcp::success);
62 | for (int i=0; i
2 |
3 | #include
4 |
5 | #include "cocoflow.h"
6 |
7 | using namespace std;
8 |
9 | #define TEST_PORT 31005
10 |
11 | #define ASSERT(x) \
12 | do { \
13 | if (!(x)) \
14 | { \
15 | fprintf(stderr, "[ASSERT]: " #x " failed at " __FILE__ ":%u\n", __LINE__); \
16 | abort(); \
17 | } \
18 | } while(0)
19 |
20 | class recv_task: public ccf::user_task
21 | {
22 | void run()
23 | {
24 | int ret;
25 | char buf[64];
26 | ccf::tcp::listening tl(1);
27 | ASSERT(tl.bind(ccf::ip_to_addr("0.0.0.0", TEST_PORT)) == 0);
28 | ccf::tcp::connected tc;
29 | ccf::tcp::accept ta(ret, tl, tc);
30 | await(ta);
31 | ASSERT(ret == ccf::tcp::success);
32 | size_t len = sizeof(buf);
33 | ccf::sleep s(500);
34 | ccf::tcp::recv_till tr0(ret, tc, buf, len);
35 | ccf::any_of any(tr0, s);
36 | await(any);
37 | ASSERT(ret == ccf::tcp::unfinished);
38 | if (any.who_completed() == 1)
39 | cout << "server cancel recv " << len << endl;
40 | len = 20;
41 | ccf::tcp::recv_till tr1(ret, tc, buf, len);
42 | await(tr1);
43 | ASSERT(ret == ccf::tcp::success);
44 | cout << "server recv " << len << endl;
45 | ccf::tcp::recv_till tr2(ret, tc, buf, len, "!!", 2);
46 | await(tr2);
47 | ASSERT(ret == ccf::tcp::success);
48 | cout << "server recv " << len << endl;
49 | }
50 | };
51 |
52 | class send_task: public ccf::user_task
53 | {
54 | void run()
55 | {
56 | int ret;
57 | char buf[64] = "hello world!!";
58 | ccf::tcp::connected tc;
59 | ccf::tcp::connect c(ret, tc, ccf::ip_to_addr("127.0.0.1", TEST_PORT));
60 | await(c);
61 | ASSERT(ret == ccf::tcp::success);
62 | ccf::tcp::send ts0(ret, tc, buf, 20);
63 | await(ts0);
64 | ASSERT(ret == ccf::tcp::success);
65 | cout << "client send 20" << endl;
66 | ccf::sleep s(1000);
67 | await(s);
68 | ccf::tcp::send ts1(ret, tc, buf, 20);
69 | await(ts1);
70 | ASSERT(ret == ccf::tcp::success);
71 | cout << "client send 20" << endl;
72 | }
73 | };
74 |
75 | class main_task: public ccf::user_task
76 | {
77 | void run()
78 | {
79 | ccf::start(new recv_task());
80 | ccf::start(new send_task());
81 | }
82 | };
83 |
84 | int main()
85 | {
86 | ccf::event_task::init(100);
87 | ccf::user_task::init(100);
88 |
89 | //ccf::set_debug(stderr);
90 |
91 | main_task tMain;
92 | ccf::cocoflow(tMain);
93 | return 0;
94 | }
95 |
--------------------------------------------------------------------------------
/test/test_tcp3.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include
4 |
5 | #include "cocoflow.h"
6 |
7 | #include "simple_rand.h"
8 |
9 | using namespace std;
10 |
11 | #define TEST_PORT 31005
12 | #define TEST_TIMES 10
13 |
14 | #define ASSERT(x) \
15 | do { \
16 | if (!(x)) \
17 | { \
18 | fprintf(stderr, "[ASSERT]: " #x " failed at " __FILE__ ":%u\n", __LINE__); \
19 | abort(); \
20 | } \
21 | } while(0)
22 |
23 | size_t get_len_from_header(const void* buf, size_t size)
24 | {
25 | if (size < sizeof(ccf::uint32))
26 | return 0;
27 | const ccf::uint32 *len = (const ccf::uint32 *)buf;
28 | return *len;
29 | }
30 |
31 | int get_seq_from_buf(const void* buf, size_t size, ccf::uint32* seq)
32 | {
33 | if (size < sizeof(ccf::uint32) + sizeof(ccf::uint32))
34 | return -1;
35 | *seq = ntohl(*(((ccf::uint32*)buf) + 1));
36 | return 0;
37 | }
38 |
39 | class echo_task: public ccf::user_task
40 | {
41 | static int times;
42 | static ccf::tcp::connected tc;
43 | void run()
44 | {
45 | int ret;
46 | char buf[1024];
47 | size_t len = sizeof(buf);
48 | ccf::uint64 t = simple_rand()%10000;
49 | ccf::tcp::recv tr(ret, echo_task::tc, buf, len);
50 | await(tr);
51 | ASSERT(ret == ccf::tcp::success);
52 | if (++echo_task::times < TEST_TIMES)
53 | ccf::start(new echo_task());
54 | cout << "echo_task recv " << len << endl;
55 | cout << "echo_task sleep " << t << endl;
56 | ccf::sleep s(t);
57 | await(s);
58 | ccf::tcp::send ts(ret, echo_task::tc, buf, len);
59 | await(ts);
60 | ASSERT(ret == ccf::tcp::success);
61 | cout << "echo_task send " << len << endl;
62 | }
63 | friend class accept_task;
64 | public:
65 | static void init()
66 | {
67 | ASSERT(echo_task::tc.bind(sizeof(ccf::uint32), 1024, get_len_from_header, get_seq_from_buf) == 0);
68 | }
69 | };
70 |
71 | int echo_task::times = 0;
72 | ccf::tcp::connected echo_task::tc;
73 |
74 | class accept_task: public ccf::user_task
75 | {
76 | static ccf::tcp::listening tl;
77 | void run()
78 | {
79 | int ret;
80 | ASSERT(accept_task::tl.bind(ccf::ip_to_addr("0.0.0.0", TEST_PORT)) == 0);
81 | ccf::tcp::accept ta(ret, accept_task::tl, echo_task::tc);
82 | await(ta);
83 | ASSERT(ret == ccf::tcp::success);
84 | echo_task::init();
85 | ccf::start(new echo_task());
86 | }
87 | };
88 |
89 | ccf::tcp::listening accept_task::tl(1);
90 |
91 | class seq_task: public ccf::user_task
92 | {
93 | static int times;
94 | static ccf::tcp::connected tc;
95 | ccf::uint32 seq;
96 | void run()
97 | {
98 | int ret;
99 | char buf[1024];
100 | ccf::uint32 *plen = (ccf::uint32 *)buf;
101 | ccf::uint32 *pseq = ((ccf::uint32 *)buf) + 1;
102 | *plen = simple_rand()%512 + 8;
103 | *pseq = htonl(this->seq);
104 | ccf::tcp::send ts(ret, seq_task::tc, buf, *plen);
105 | await(ts);
106 | ASSERT(ret == ccf::tcp::success);
107 | cout << "seq_task send " << *plen << ", seq = " << this->seq << endl;
108 | size_t len = sizeof(buf);
109 | ccf::tcp::recv_by_seq_u32 tr(ret, seq_task::tc, buf, len, this->seq);
110 | await(tr);
111 | ASSERT(ret == ccf::tcp::success);
112 | cout << "seq_task recv " << len << ", seq = " << this->seq << endl;
113 | if (++seq_task::times == TEST_TIMES)
114 | exit(0);
115 | }
116 | public:
117 | static void init()
118 | {
119 | int ret;
120 | ccf::tcp::connect c(ret, seq_task::tc, ccf::ip_to_addr("127.0.0.1", TEST_PORT));
121 | await(c);
122 | ASSERT(ret == ccf::tcp::success);
123 | ASSERT(seq_task::tc.bind(sizeof(ccf::uint32), 1024, get_len_from_header, get_seq_from_buf) == 0);
124 | }
125 | seq_task(ccf::uint32 seq) : seq(seq) {}
126 | };
127 |
128 | int seq_task::times = 0;
129 | ccf::tcp::connected seq_task::tc;
130 |
131 | class main_task: public ccf::user_task
132 | {
133 | void run()
134 | {
135 | ccf::start(new accept_task());
136 | seq_task::init();
137 | for (int i=0; i
2 |
3 | #include
4 |
5 | #include "cocoflow.h"
6 |
7 | using namespace std;
8 |
9 | #define TEST_PORT 30917
10 | #define TEST_TIMES 10
11 |
12 | #define ASSERT(x) \
13 | do { \
14 | if (!(x)) \
15 | { \
16 | fprintf(stderr, "[ASSERT]: " #x " failed at " __FILE__ ":%u\n", __LINE__); \
17 | abort(); \
18 | } \
19 | } while(0)
20 |
21 | class recv_task: public ccf::user_task
22 | {
23 | void run()
24 | {
25 | ccf::udp u;
26 | char buf[65536];
27 | ASSERT(u.bind(ccf::ip_to_addr("0.0.0.0", TEST_PORT)) == 0);
28 | for (int i=0; i
2 |
3 | #include
4 |
5 | #include "cocoflow.h"
6 |
7 | #include "simple_rand.h"
8 |
9 | using namespace std;
10 |
11 | #define TEST_PORT 30917
12 | #define TEST_TIMES 10
13 |
14 | #define ASSERT(x) \
15 | do { \
16 | if (!(x)) \
17 | { \
18 | fprintf(stderr, "[ASSERT]: " #x " failed at " __FILE__ ":%u\n", __LINE__); \
19 | abort(); \
20 | } \
21 | } while(0)
22 |
23 | class echo_task: public ccf::user_task
24 | {
25 | void run()
26 | {
27 | ccf::udp u;
28 | char buf[65536];
29 | struct sockaddr_in peer;
30 | ASSERT(u.bind(ccf::ip_to_addr("0.0.0.0", TEST_PORT)) == 0);
31 | for (int i=0; iy;
29 | }
30 | };
31 |
32 | class echo_task: public ccf::user_task
33 | {
34 | static int times;
35 | static ccf::udp u;
36 | void run()
37 | {
38 | char buf[65536];
39 | struct sockaddr_in peer;
40 | size_t len = sizeof(buf);
41 | ccf::uint64 t = simple_rand()%10000;
42 | ccf::udp::recv ur(echo_task::u, buf, len);
43 | await(ur);
44 | ASSERT(ur.peer_type() == AF_INET);
45 | peer = ur.peer_addr_ipv4();
46 | if (++echo_task::times < TEST_TIMES)
47 | ccf::start(new echo_task());
48 | cout << "echo_task recv " << len << " from " << ccf::ip_to_str(peer) << endl;
49 | cout << "echo_task sleep " << t << endl;
50 | ccf::sleep s(t);
51 | await(s);
52 | ccf::udp::send us(echo_task::u, peer, buf, len);
53 | await(us);
54 | cout << "echo_task send " << len << " to " << ccf::ip_to_str(peer) << endl;
55 | }
56 | public:
57 | static void init()
58 | {
59 | ASSERT(u.bind(ccf::ip_to_addr("0.0.0.0", TEST_PORT)) == 0);
60 | }
61 | };
62 |
63 | int echo_task::times = 0;
64 | ccf::udp echo_task::u;
65 |
66 | int get_seq_from_buf(const void* buf, size_t size, ccf::uint32* seq)
67 | {
68 | if (size < sizeof(ccf::uint32))
69 | return -1;
70 | *seq = ntohl(*(ccf::uint32*)buf);
71 | return 0;
72 | }
73 |
74 | class seq_task: public ccf::user_task
75 | {
76 | static int times;
77 | static ccf::udp u;
78 | static struct sockaddr_in target;
79 | ccf::uint32 seq;
80 | void run()
81 | {
82 | char buf[65536];
83 | ccf::uint32 *pos = (ccf::uint32 *)buf;
84 | *pos = htonl(this->seq);
85 | int add_len = simple_rand()%100;
86 | ccf::udp::send us(seq_task::u, seq_task::target, buf, sizeof(ccf::uint32) + add_len);
87 | await(us);
88 | cout << "seq_task send " << sizeof(ccf::uint32) + add_len << ", seq = " << this->seq << endl;
89 | size_t len = sizeof(buf);
90 | ccf::udp::recv_by_seq_u32 ur(seq_task::u, buf, len, this->seq);
91 | await(ur);
92 | cout << "seq_task recv " << len << ", seq = " << this->seq << endl;
93 | if (++seq_task::times == TEST_TIMES)
94 | exit(0);
95 | }
96 | public:
97 | static void init()
98 | {
99 | seq_task::target = ccf::ip_to_addr("127.0.0.1", TEST_PORT);
100 | ASSERT(seq_task::u.bind(get_seq_from_buf) == 0);
101 | }
102 | seq_task(ccf::uint32 seq) : seq(seq) {}
103 | };
104 |
105 | int seq_task::times = 0;
106 | ccf::udp seq_task::u;
107 | struct sockaddr_in seq_task::target;
108 |
109 | class main_task: public ccf::user_task
110 | {
111 | void run()
112 | {
113 | echo_task::init();
114 | seq_task::init();
115 | ccf::start(new echo_task());
116 | for (int i=0; i
2 | #include
3 | #include
4 |
5 | #define TEST_TIMES 100000
6 |
7 | ucontext_t ucs[2];
8 |
9 | char sBufs[TEST_TIMES][2048];
10 |
11 | void ping()
12 | {
13 | }
14 |
15 | int main()
16 | {
17 | int i;
18 | clock_t tBgn, tEnd;
19 |
20 | tBgn = clock();
21 |
22 | for (i=0; i
2 | #include
3 | #include
4 |
5 | #define TEST_TIMES 100000
6 |
7 | ucontext_t ucs[TEST_TIMES + 1];
8 |
9 | char sBufs[TEST_TIMES][4096];
10 |
11 | void ping()
12 | {
13 | }
14 |
15 | int main()
16 | {
17 | int i;
18 | clock_t tBgn, tEnd, tBrk1, tBrk2, tBrk3;
19 |
20 | tBgn = clock();
21 |
22 | for (i=0; i
2 | #include
3 | #include
4 |
5 | #define TEST_TIMES 100000
6 |
7 | ucontext_t ucs[TEST_TIMES + 1];
8 |
9 | char sBufs[TEST_TIMES][2048];
10 |
11 | void ping()
12 | {
13 | }
14 |
15 | int main()
16 | {
17 | int i;
18 | clock_t tBgn, tEnd, tBrk1, tBrk2, tBrk3;
19 |
20 | tBgn = clock();
21 |
22 | for (i=0; i
2 | #include
3 | #include
4 |
5 | #define TEST_TIMES 100000
6 |
7 | ucontext_t ucs[TEST_TIMES + 1];
8 |
9 | char sBufs[TEST_TIMES][512];
10 |
11 | void ping()
12 | {
13 | }
14 |
15 | int main()
16 | {
17 | int i;
18 | clock_t tBgn, tEnd, tBrk1, tBrk2, tBrk3;
19 |
20 | tBgn = clock();
21 |
22 | for (i=0; i
2 | #include
3 | #include
4 |
5 | #define TEST_TIMES 100000
6 |
7 | ucontext_t ucs[TEST_TIMES + 1];
8 |
9 | char sBufs[TEST_TIMES][32768];
10 |
11 | void ping()
12 | {
13 | }
14 |
15 | int main()
16 | {
17 | int i;
18 | clock_t tBgn, tEnd, tBrk1, tBrk2, tBrk3;
19 |
20 | tBgn = clock();
21 |
22 | for (i=0; i
2 | #include
3 | #include
4 |
5 | #define TEST_TIMES 100000
6 |
7 | ucontext_t ucs[3];
8 |
9 | char sBuf1[4096];
10 | char sBuf2[4096];
11 |
12 | void ping()
13 | {
14 | int i;
15 | for (i=0; i
2 | #include
3 | #include
4 |
5 | #define TEST_TIMES 100000
6 |
7 | ucontext_t ucs[2];
8 |
9 | char sBuf[4096];
10 |
11 | void ping()
12 | {
13 | }
14 |
15 | int main()
16 | {
17 | int i;
18 | clock_t tBgn, tEnd;
19 |
20 | tBgn = clock();
21 |
22 | for (i=0; i
2 |
3 | #include "cocoflow.h"
4 |
5 | using namespace std;
6 |
7 | #define TEST_PORT 31005
8 | #ifdef _WIN32
9 | #define TEST_TIMES 1000 //lite
10 | #else
11 | #define TEST_TIMES 10000
12 | #endif
13 | #define TEST_SIZE 800
14 |
15 | #define ASSERT(x) \
16 | do { \
17 | if (!(x)) \
18 | { \
19 | fprintf(stderr, "[ASSERT]: " #x " failed at " __FILE__ ":%u\n", __LINE__); \
20 | abort(); \
21 | } \
22 | } while(0)
23 |
24 | typedef ccf::task<15> test_task;
25 |
26 | static int recv_bytes = 0, send_bytes = 0;
27 |
28 | class recv_task: public test_task
29 | {
30 | void run()
31 | {
32 | int ret;
33 | ccf::tcp::listening tl(1);
34 | ccf::tcp::connected tc;
35 | ASSERT(tl.bind(ccf::ip_to_addr("0.0.0.0", TEST_PORT)) == 0);
36 | ccf::tcp::accept ta(ret, tl, tc);
37 | await(ta);
38 | ASSERT(ret == ccf::tcp::success);
39 | for (;;)
40 | {
41 | char buf[8192];
42 | size_t len = sizeof(buf);
43 | ccf::tcp::recv tr(ret, tc, buf, len);
44 | await(tr);
45 | ASSERT(ret == ccf::tcp::success);
46 | recv_bytes += len;
47 | if (recv_bytes > send_bytes)
48 | cout << "recv(" << recv_bytes << ") > send(" << send_bytes << ")" << endl;
49 | if (recv_bytes == TEST_TIMES * TEST_SIZE)
50 | exit(0);
51 | }
52 | }
53 | };
54 |
55 | class send_task: public test_task
56 | {
57 | static ccf::tcp::connected tc;
58 | void run()
59 | {
60 | int ret;
61 | char buf[TEST_SIZE];
62 | ccf::tcp::send ts(ret, send_task::tc, buf, sizeof(buf));
63 | await(ts);
64 | ASSERT(ret == ccf::tcp::success);
65 | send_bytes += sizeof(buf);
66 | }
67 | public:
68 | static void init()
69 | {
70 | int ret;
71 | ccf::tcp::connect c(ret, send_task::tc, ccf::ip_to_addr("127.0.0.1", TEST_PORT));
72 | await(c);
73 | ASSERT(ret == ccf::tcp::success);
74 | }
75 | };
76 |
77 | ccf::tcp::connected send_task::tc;
78 |
79 | class main_task: public test_task
80 | {
81 | void run()
82 | {
83 | ccf::start(new recv_task());
84 | send_task::init();
85 | for (int i=0; istatus() == ccf::ready);
89 | ccf::start(st);
90 | }
91 | }
92 | };
93 |
94 | int main()
95 | {
96 | ccf::event_task::init(1);
97 | test_task::init(TEST_TIMES + 2);
98 | main_task tMain;
99 |
100 | ccf::cocoflow(tMain);
101 |
102 | return 0;
103 | }
104 |
--------------------------------------------------------------------------------
/vc/benchmark_tcp.vcproj:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
14 |
17 |
18 |
19 |
20 |
21 |
28 |
31 |
34 |
37 |
40 |
43 |
53 |
56 |
59 |
62 |
70 |
73 |
76 |
79 |
82 |
85 |
88 |
91 |
92 |
100 |
103 |
106 |
109 |
112 |
115 |
125 |
128 |
131 |
134 |
144 |
147 |
150 |
153 |
156 |
159 |
162 |
165 |
166 |
173 |
176 |
179 |
182 |
185 |
189 |
199 |
202 |
205 |
208 |
216 |
219 |
222 |
225 |
228 |
231 |
234 |
237 |
238 |
246 |
249 |
252 |
255 |
258 |
262 |
272 |
275 |
278 |
281 |
291 |
294 |
297 |
300 |
303 |
306 |
309 |
312 |
313 |
314 |
315 |
316 |
317 |
322 |
325 |
326 |
327 |
332 |
333 |
338 |
339 |
340 |
341 |
342 |
343 |
--------------------------------------------------------------------------------
/vc/benchmark_udp.vcproj:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
14 |
17 |
18 |
19 |
20 |
21 |
28 |
31 |
34 |
37 |
40 |
43 |
53 |
56 |
59 |
62 |
70 |
73 |
76 |
79 |
82 |
85 |
88 |
91 |
92 |
100 |
103 |
106 |
109 |
112 |
115 |
125 |
128 |
131 |
134 |
144 |
147 |
150 |
153 |
156 |
159 |
162 |
165 |
166 |
173 |
176 |
179 |
182 |
185 |
189 |
199 |
202 |
205 |
208 |
216 |
219 |
222 |
225 |
228 |
231 |
234 |
237 |
238 |
246 |
249 |
252 |
255 |
258 |
262 |
272 |
275 |
278 |
281 |
291 |
294 |
297 |
300 |
303 |
306 |
309 |
312 |
313 |
314 |
315 |
316 |
317 |
322 |
325 |
326 |
327 |
332 |
333 |
338 |
339 |
340 |
341 |
342 |
343 |
--------------------------------------------------------------------------------
/vc/demo_all_sort.vcproj:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
14 |
17 |
18 |
19 |
20 |
21 |
28 |
31 |
34 |
37 |
40 |
43 |
53 |
56 |
59 |
62 |
70 |
73 |
76 |
79 |
82 |
85 |
88 |
91 |
92 |
100 |
103 |
106 |
109 |
112 |
115 |
125 |
128 |
131 |
134 |
144 |
147 |
150 |
153 |
156 |
159 |
162 |
165 |
166 |
173 |
176 |
179 |
182 |
185 |
189 |
199 |
202 |
205 |
208 |
216 |
219 |
222 |
225 |
228 |
231 |
234 |
237 |
238 |
246 |
249 |
252 |
255 |
258 |
262 |
272 |
275 |
278 |
281 |
291 |
294 |
297 |
300 |
303 |
306 |
309 |
312 |
313 |
314 |
315 |
316 |
317 |
322 |
325 |
326 |
327 |
332 |
333 |
338 |
339 |
340 |
341 |
342 |
343 |
--------------------------------------------------------------------------------
/vc/libccf.vcproj:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
15 |
18 |
19 |
20 |
21 |
22 |
29 |
32 |
35 |
38 |
41 |
44 |
57 |
60 |
63 |
66 |
69 |
72 |
75 |
78 |
81 |
84 |
85 |
93 |
96 |
99 |
102 |
105 |
108 |
118 |
121 |
124 |
127 |
130 |
133 |
136 |
139 |
142 |
145 |
146 |
153 |
156 |
159 |
162 |
165 |
169 |
182 |
185 |
188 |
191 |
194 |
197 |
200 |
203 |
206 |
209 |
210 |
218 |
221 |
224 |
227 |
230 |
234 |
244 |
247 |
250 |
253 |
256 |
259 |
262 |
265 |
268 |
271 |
272 |
273 |
274 |
275 |
276 |
281 |
284 |
285 |
288 |
289 |
292 |
293 |
296 |
297 |
300 |
301 |
304 |
305 |
308 |
309 |
310 |
315 |
316 |
321 |
322 |
323 |
324 |
325 |
326 |
--------------------------------------------------------------------------------
/vc/test.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | cd %~dp0
4 |
5 | cd Release
6 |
7 | echo test primitive
8 | (test_primitive && echo Succeed) || echo Failed
9 | echo test sleep
10 | (test_sleep > nul && echo Succeed) || echo Failed
11 | echo test udp [3]
12 | (test_udp > nul && echo Succeed) || echo Failed
13 | (test_udp2 > nul && echo Succeed) || echo Failed
14 | (test_udp3 > nul && echo Succeed) || echo Failed
15 | echo test tcp [3]
16 | (test_tcp > nul && echo Succeed) || echo Failed
17 | (test_tcp2 > nul && echo Succeed) || echo Failed
18 | (test_tcp3 > nul && echo Succeed) || echo Failed
19 | echo test tcp timing (lite)
20 | (unexpected_tcp_timing > nul && echo Succeed) || echo Failed
21 | echo test getaddrinfo
22 | (test_getaddrinfo > nul && echo Succeed) || echo Failed
23 | echo benchmark sleep
24 | (benchmark_sleep > nul && echo Succeed) || echo Failed
25 | echo benchmark udp (lite)
26 | (benchmark_udp2 > nul && echo Succeed) || echo Failed
27 | echo benchmark tcp (lite)
28 | (benchmark_tcp > nul && echo Succeed) || echo Failed
29 |
30 | pause
31 |
--------------------------------------------------------------------------------
/vc/test_sleep.vcproj:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
14 |
17 |
18 |
19 |
20 |
21 |
28 |
31 |
34 |
37 |
40 |
43 |
53 |
56 |
59 |
62 |
70 |
73 |
76 |
79 |
82 |
85 |
88 |
91 |
92 |
100 |
103 |
106 |
109 |
112 |
115 |
125 |
128 |
131 |
134 |
144 |
147 |
150 |
153 |
156 |
159 |
162 |
165 |
166 |
173 |
176 |
179 |
182 |
185 |
189 |
199 |
202 |
205 |
208 |
216 |
219 |
222 |
225 |
228 |
231 |
234 |
237 |
238 |
246 |
249 |
252 |
255 |
258 |
262 |
272 |
275 |
278 |
281 |
291 |
294 |
297 |
300 |
303 |
306 |
309 |
312 |
313 |
314 |
315 |
316 |
317 |
322 |
325 |
326 |
327 |
332 |
333 |
338 |
339 |
340 |
341 |
342 |
343 |
--------------------------------------------------------------------------------
/vc/test_tcp.vcproj:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
14 |
17 |
18 |
19 |
20 |
21 |
28 |
31 |
34 |
37 |
40 |
43 |
53 |
56 |
59 |
62 |
70 |
73 |
76 |
79 |
82 |
85 |
88 |
91 |
92 |
100 |
103 |
106 |
109 |
112 |
115 |
125 |
128 |
131 |
134 |
144 |
147 |
150 |
153 |
156 |
159 |
162 |
165 |
166 |
173 |
176 |
179 |
182 |
185 |
189 |
199 |
202 |
205 |
208 |
216 |
219 |
222 |
225 |
228 |
231 |
234 |
237 |
238 |
246 |
249 |
252 |
255 |
258 |
262 |
272 |
275 |
278 |
281 |
291 |
294 |
297 |
300 |
303 |
306 |
309 |
312 |
313 |
314 |
315 |
316 |
317 |
322 |
325 |
326 |
327 |
332 |
333 |
338 |
339 |
340 |
341 |
342 |
343 |
--------------------------------------------------------------------------------
/vc/test_tcp2.vcproj:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
14 |
17 |
18 |
19 |
20 |
21 |
28 |
31 |
34 |
37 |
40 |
43 |
53 |
56 |
59 |
62 |
70 |
73 |
76 |
79 |
82 |
85 |
88 |
91 |
92 |
100 |
103 |
106 |
109 |
112 |
115 |
125 |
128 |
131 |
134 |
144 |
147 |
150 |
153 |
156 |
159 |
162 |
165 |
166 |
173 |
176 |
179 |
182 |
185 |
189 |
199 |
202 |
205 |
208 |
216 |
219 |
222 |
225 |
228 |
231 |
234 |
237 |
238 |
246 |
249 |
252 |
255 |
258 |
262 |
272 |
275 |
278 |
281 |
291 |
294 |
297 |
300 |
303 |
306 |
309 |
312 |
313 |
314 |
315 |
316 |
317 |
322 |
325 |
326 |
327 |
332 |
333 |
338 |
339 |
340 |
341 |
342 |
343 |
--------------------------------------------------------------------------------
/vc/test_tcp3.vcproj:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
14 |
17 |
18 |
19 |
20 |
21 |
28 |
31 |
34 |
37 |
40 |
43 |
53 |
56 |
59 |
62 |
70 |
73 |
76 |
79 |
82 |
85 |
88 |
91 |
92 |
100 |
103 |
106 |
109 |
112 |
115 |
125 |
128 |
131 |
134 |
144 |
147 |
150 |
153 |
156 |
159 |
162 |
165 |
166 |
173 |
176 |
179 |
182 |
185 |
189 |
199 |
202 |
205 |
208 |
216 |
219 |
222 |
225 |
228 |
231 |
234 |
237 |
238 |
246 |
249 |
252 |
255 |
258 |
262 |
272 |
275 |
278 |
281 |
291 |
294 |
297 |
300 |
303 |
306 |
309 |
312 |
313 |
314 |
315 |
316 |
317 |
322 |
325 |
326 |
327 |
332 |
333 |
338 |
339 |
340 |
341 |
342 |
343 |
--------------------------------------------------------------------------------
/vc/test_udp.vcproj:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
14 |
17 |
18 |
19 |
20 |
21 |
28 |
31 |
34 |
37 |
40 |
43 |
53 |
56 |
59 |
62 |
70 |
73 |
76 |
79 |
82 |
85 |
88 |
91 |
92 |
100 |
103 |
106 |
109 |
112 |
115 |
125 |
128 |
131 |
134 |
144 |
147 |
150 |
153 |
156 |
159 |
162 |
165 |
166 |
173 |
176 |
179 |
182 |
185 |
189 |
199 |
202 |
205 |
208 |
216 |
219 |
222 |
225 |
228 |
231 |
234 |
237 |
238 |
246 |
249 |
252 |
255 |
258 |
262 |
272 |
275 |
278 |
281 |
291 |
294 |
297 |
300 |
303 |
306 |
309 |
312 |
313 |
314 |
315 |
316 |
317 |
322 |
325 |
326 |
327 |
332 |
333 |
338 |
339 |
340 |
341 |
342 |
343 |
--------------------------------------------------------------------------------
/vc/test_udp2.vcproj:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
14 |
17 |
18 |
19 |
20 |
21 |
28 |
31 |
34 |
37 |
40 |
43 |
53 |
56 |
59 |
62 |
70 |
73 |
76 |
79 |
82 |
85 |
88 |
91 |
92 |
100 |
103 |
106 |
109 |
112 |
115 |
125 |
128 |
131 |
134 |
144 |
147 |
150 |
153 |
156 |
159 |
162 |
165 |
166 |
173 |
176 |
179 |
182 |
185 |
189 |
199 |
202 |
205 |
208 |
216 |
219 |
222 |
225 |
228 |
231 |
234 |
237 |
238 |
246 |
249 |
252 |
255 |
258 |
262 |
272 |
275 |
278 |
281 |
291 |
294 |
297 |
300 |
303 |
306 |
309 |
312 |
313 |
314 |
315 |
316 |
317 |
322 |
325 |
326 |
327 |
332 |
333 |
338 |
339 |
340 |
341 |
342 |
343 |
--------------------------------------------------------------------------------
/vc/test_udp3.vcproj:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
14 |
17 |
18 |
19 |
20 |
21 |
28 |
31 |
34 |
37 |
40 |
43 |
53 |
56 |
59 |
62 |
70 |
73 |
76 |
79 |
82 |
85 |
88 |
91 |
92 |
100 |
103 |
106 |
109 |
112 |
115 |
125 |
128 |
131 |
134 |
144 |
147 |
150 |
153 |
156 |
159 |
162 |
165 |
166 |
173 |
176 |
179 |
182 |
185 |
189 |
199 |
202 |
205 |
208 |
216 |
219 |
222 |
225 |
228 |
231 |
234 |
237 |
238 |
246 |
249 |
252 |
255 |
258 |
262 |
272 |
275 |
278 |
281 |
291 |
294 |
297 |
300 |
303 |
306 |
309 |
312 |
313 |
314 |
315 |
316 |
317 |
322 |
325 |
326 |
327 |
332 |
333 |
338 |
339 |
340 |
341 |
342 |
343 |
--------------------------------------------------------------------------------
/vc/test_x64.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | cd %~dp0
4 |
5 | cd x64\Release
6 |
7 | echo test primitive
8 | (test_primitive && echo Succeed) || echo Failed
9 | echo test sleep
10 | (test_sleep > nul && echo Succeed) || echo Failed
11 | echo test udp [3]
12 | (test_udp > nul && echo Succeed) || echo Failed
13 | (test_udp2 > nul && echo Succeed) || echo Failed
14 | (test_udp3 > nul && echo Succeed) || echo Failed
15 | echo test tcp [3]
16 | (test_tcp > nul && echo Succeed) || echo Failed
17 | (test_tcp2 > nul && echo Succeed) || echo Failed
18 | (test_tcp3 > nul && echo Succeed) || echo Failed
19 | echo test tcp timing
20 | (unexpected_tcp_timing > nul && echo Succeed) || echo Failed
21 | echo test getaddrinfo
22 | (test_getaddrinfo > nul && echo Succeed) || echo Failed
23 | echo benchmark sleep
24 | (benchmark_sleep > nul && echo Succeed) || echo Failed
25 | echo benchmark udp
26 | (benchmark_udp2 > nul && echo Succeed) || echo Failed
27 | echo benchmark tcp
28 | (benchmark_tcp > nul && echo Succeed) || echo Failed
29 |
30 | pause
31 |
--------------------------------------------------------------------------------
/vcbuild.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | cd %~dp0
4 |
5 | set CCF_UV_VERSION=0.10.27
6 |
7 | set CCF_PLATFORM=x86
8 | if "%PROCESSOR_ARCHITECTURE%"=="AMD64" set CCF_PLATFORM=x64
9 | if "%1"=="x86" set CCF_PLATFORM=x86
10 | if "%1"=="x64" set CCF_PLATFORM=x64
11 |
12 | set CCF_MS_PLATFORM=WIN32
13 | if "%CCF_PLATFORM%"=="x64" set CCF_MS_PLATFORM=WIN64
14 | set CCF_LIB_PATH=
15 | if "%CCF_PLATFORM%"=="x64" set CCF_LIB_PATH=x64\
16 |
17 | if exist lib\Release\libuv.lib goto check_msvc
18 |
19 | echo Compiling libuv ...
20 | cd deps
21 | unzip gyp.zip > nul
22 | unzip libuv-%CCF_UV_VERSION%.zip > nul
23 | cd libuv-%CCF_UV_VERSION%\
24 | md build
25 | md build\gyp
26 | xcopy /E ..\gyp build\gyp > nul
27 | call vcbuild debug %CCF_PLATFORM%
28 | call vcbuild release %CCF_PLATFORM%
29 |
30 | cd %~dp0
31 | md src\uv
32 | xcopy /E deps\libuv-%CCF_UV_VERSION%\include src\uv > nul
33 | md lib\Debug
34 | md lib\Release
35 | xcopy deps\libuv-%CCF_UV_VERSION%\Debug\lib\libuv.lib lib\Debug\ > nul
36 | xcopy deps\libuv-%CCF_UV_VERSION%\Release\lib\libuv.lib lib\Release\ > nul
37 |
38 | :check_msvc
39 | @rem Look for Visual Studio 2013
40 | if not defined VS120COMNTOOLS goto vc-set-2012
41 | if not exist "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2012
42 | call "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" %CCF_PLATFORM%
43 | goto upgrade
44 |
45 | :vc-set-2012
46 | @rem Look for Visual Studio 2012
47 | if not defined VS110COMNTOOLS goto vc-set-2010
48 | if not exist "%VS110COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2010
49 | call "%VS110COMNTOOLS%\..\..\vc\vcvarsall.bat" %CCF_PLATFORM%
50 | goto upgrade
51 |
52 | :vc-set-2010
53 | @rem Look for Visual Studio 2010
54 | if not defined VS100COMNTOOLS goto vc-set-2008
55 | if not exist "%VS100COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2008
56 | call "%VS100COMNTOOLS%\..\..\vc\vcvarsall.bat" %CCF_PLATFORM%
57 | goto upgrade
58 |
59 | :vc-set-2008
60 | @rem Look for Visual Studio 2008
61 | if not defined VS90COMNTOOLS goto vc-set-notfound
62 | if not exist "%VS90COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-notfound
63 | call "%VS90COMNTOOLS%\..\..\vc\vcvarsall.bat" %CCF_PLATFORM%
64 | goto msbuild
65 |
66 | :vc-set-notfound
67 | echo Error: Visual Studio not found
68 | goto exit
69 |
70 | :upgrade
71 | echo Upgrading for Visual Studio ...
72 | devenv /upgrade vc\cocoflow.sln
73 |
74 | :msbuild
75 | echo Compiling libccf ...
76 | msbuild vc\cocoflow.sln /t:libccf /p:Configuration=Debug /p:Platform="%CCF_MS_PLATFORM%" /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo
77 | msbuild vc\cocoflow.sln /t:libccf /p:Configuration=Release /p:Platform="%CCF_MS_PLATFORM%" /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo
78 | xcopy /Y vc\%CCF_LIB_PATH%Debug\libccf.lib lib\Debug\ > nul
79 | xcopy /Y vc\%CCF_LIB_PATH%Release\libccf.lib lib\Release\ > nul
80 |
81 | echo Compiling demo ...
82 | msbuild vc\cocoflow.sln /t:demo_all_sort,demo_any_sort,demo_http_server /p:Configuration=Debug /p:Platform="%CCF_MS_PLATFORM%" /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo
83 | msbuild vc\cocoflow.sln /t:demo_all_sort,demo_any_sort,demo_http_server /p:Configuration=Release /p:Platform="%CCF_MS_PLATFORM%" /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo
84 |
85 | echo Compiling test ...
86 | msbuild vc\cocoflow.sln /t:test_primitive,test_sleep,test_tcp,test_tcp2,test_tcp3,test_udp,test_udp2,test_udp3,unexpected_tcp_timing,test_getaddrinfo /p:Configuration=Debug /p:Platform="%CCF_MS_PLATFORM%" /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo
87 | msbuild vc\cocoflow.sln /t:test_primitive,test_sleep,test_tcp,test_tcp2,test_tcp3,test_udp,test_udp2,test_udp3,unexpected_tcp_timing,test_getaddrinfo /p:Configuration=Release /p:Platform="%CCF_MS_PLATFORM%" /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo
88 | msbuild vc\cocoflow.sln /t:benchmark_sleep,benchmark_tcp,benchmark_udp,benchmark_udp2 /p:Configuration=Debug /p:Platform="%CCF_MS_PLATFORM%" /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo
89 | msbuild vc\cocoflow.sln /t:benchmark_sleep,benchmark_tcp,benchmark_udp,benchmark_udp2 /p:Configuration=Release /p:Platform="%CCF_MS_PLATFORM%" /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo
90 |
91 | :exit
92 | pause
93 |
--------------------------------------------------------------------------------