Skip to content

Commit f8d2ac5

Browse files
committed
encounter the problem with libdispatch
have to roll out my own version of dispatch_main_queue :-(
1 parent c5f1271 commit f8d2ac5

File tree

11 files changed

+187
-25
lines changed

11 files changed

+187
-25
lines changed

lib/ccv_sift.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ inline static double _ccv_keypoint_interpolate(float N9[3][9], int ix, int iy, i
5454
{
5555
double maxa = 0;
5656
double maxabsa = 0;
57-
int maxi = -1;
57+
int maxi = j;
5858
double tmp;
5959

6060
/* look for the maximally stable pivot */

serve/async.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#include <stdlib.h>
2+
#include <ev.h>
3+
#include <dispatch/dispatch.h>
4+
5+
typedef struct {
6+
void *context;
7+
void (*cb)(void*);
8+
} main_async_t;
9+
10+
static dispatch_semaphore_t async_queue_semaphore;
11+
static int queue_position = 0;
12+
static int queue_pending = 0;
13+
static int queue_length = 10;
14+
static main_async_t* async_queue;
15+
static ev_async main_async;
16+
17+
void dispatch_main_async_f(void* context, void (*cb)(void*))
18+
{
19+
dispatch_semaphore_wait(async_queue_semaphore, DISPATCH_TIME_FOREVER);
20+
++queue_pending;
21+
if (queue_pending > queue_length)
22+
{
23+
queue_length = (queue_length * 3 + 1) / 2;
24+
async_queue = (main_async_t*)realloc(async_queue, sizeof(main_async_t) * queue_length);
25+
}
26+
async_queue[queue_position].context = context;
27+
async_queue[queue_position].cb = cb;
28+
queue_position = (queue_position + 1) % queue_length;
29+
dispatch_semaphore_signal(async_queue_semaphore);
30+
ev_async_send(EV_DEFAULT_ &main_async);
31+
}
32+
33+
static void main_async_dispatch(EV_P_ ev_async* w, int revents)
34+
{
35+
dispatch_semaphore_wait(async_queue_semaphore, DISPATCH_TIME_FOREVER);
36+
while (queue_pending > 0)
37+
{
38+
queue_position = (queue_position + queue_length - 1) % queue_length;
39+
--queue_pending;
40+
async_queue[queue_position].cb(async_queue[queue_position].context);
41+
}
42+
dispatch_semaphore_signal(async_queue_semaphore);
43+
}
44+
45+
void main_async_init(void)
46+
{
47+
async_queue_semaphore = dispatch_semaphore_create(1);
48+
async_queue = (main_async_t*)malloc(sizeof(main_async_t) * queue_length);
49+
ev_async_init(&main_async, main_async_dispatch);
50+
}
51+
52+
void main_async_start(EV_P)
53+
{
54+
ev_async_start(EV_A_ &main_async);
55+
}
56+
57+
void main_async_destroy(void)
58+
{
59+
dispatch_release(async_queue_semaphore);
60+
free(async_queue);
61+
}

serve/async.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#ifndef _GUARD_async_h_
2+
#define _GUARD_async_h_
3+
4+
void dispatch_main_async_f(void* context, void (*cb)(void*));
5+
void main_async_init(void);
6+
void main_async_start(EV_P);
7+
void main_async_destroy(void);
8+
9+
#endif

serve/bbf.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include "uri.h"
2+
3+
#define MSG ("HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 12\r\n\r\nhello world\n")
4+
5+
ebb_buf ebb_bbf_detect_objects(const void* query)
6+
{
7+
ebb_buf buf;
8+
buf.data = MSG;
9+
buf.len = sizeof(MSG);
10+
return buf;
11+
}

serve/ebb.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ ebb_connection_init(ebb_connection *connection)
431431
}
432432

433433
void
434-
ebb_connection_schedule_close (ebb_connection *connection)
434+
ebb_connection_schedule_close(ebb_connection *connection)
435435
{
436436
ev_timer_start(connection->server->loop, &connection->goodbye_watcher);
437437
}
@@ -456,7 +456,7 @@ ebb_connection_reset_timeout(ebb_connection *connection)
456456
* will return 0 and ignore the request.
457457
*/
458458
int
459-
ebb_connection_write (ebb_connection *connection, const char *buf, size_t len, ebb_after_write_cb cb)
459+
ebb_connection_write(ebb_connection *connection, const char *buf, size_t len, ebb_after_write_cb cb)
460460
{
461461
if(ev_is_active(&connection->write_watcher))
462462
return 0;

serve/makefile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
include ../lib/config.mk
22
#CC += -faddress-sanitizer -fno-omit-frame-pointer
3-
LDFLAGS := -L"../lib" -lccv -lev -lBlocksRuntime -ldispatch $(LDFLAGS)
4-
CFLAGS := -O3 -Wall -fblocks -I"../lib" $(CFLAGS)
3+
LDFLAGS := -L"../lib" -lccv -lev -ldispatch $(LDFLAGS)
4+
CFLAGS := -O3 -Wall -I"../lib" $(CFLAGS)
55

66
TARGETS = ccv
77

@@ -10,8 +10,8 @@ all: libccv.a $(TARGETS)
1010
clean:
1111
${MAKE} clean -C ../lib ; rm *.o $(TARGETS) -f
1212

13-
$(TARGETS): serve.o ebb.o ebb_request_parser.o libccv.a
14-
$(CC) -o $@ serve.o ebb.o ebb_request_parser.o $(LDFLAGS)
13+
$(TARGETS): serve.o uri.o bbf.o async.o ebb.o ebb_request_parser.o libccv.a
14+
$(CC) -o $@ serve.o uri.o bbf.o async.o ebb.o ebb_request_parser.o $(LDFLAGS)
1515

1616
libccv.a:
1717
${MAKE} -C ../lib

serve/serve.c

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,46 +2,79 @@
22
#include <ev.h>
33
#include <dispatch/dispatch.h>
44
#include "ebb.h"
5+
#include "uri.h"
6+
#include "async.h"
7+
8+
static const char* ebb_http_404 = "HTTP/1.1 404 Not Found\r\nContent-Type: text/plain\r\nContent-Length: 4\r\n\r\n404\n";
9+
10+
typedef struct {
11+
ebb_request* request;
12+
} ebb_connection_extras;
513

614
typedef struct {
715
ebb_connection* connection;
8-
ebb_buf* responses;
16+
ccv_uri_dispatch_t* dispatcher;
17+
char* query;
18+
ebb_buf response;
919
} ebb_request_extras;
1020

11-
static ev_async main_async;
21+
static void on_request_path(ebb_request* request, const char* at, size_t length)
22+
{
23+
ebb_request_extras* extras = (ebb_request_extras*)request->data;
24+
char* path = (char*)at;
25+
char eof = path[length];
26+
path[length] = '\0';
27+
extras->dispatcher = find_uri_dispatch(path);
28+
path[length] = eof;
29+
}
1230

13-
static void dispatch_main_async(dispatch_block_t block)
31+
static void on_request_query_string(ebb_request* request, const char* at, size_t length)
1432
{
15-
dispatch_async(dispatch_get_main_queue(), block);
16-
ev_async_send(EV_DEFAULT_ &main_async);
33+
ebb_request_extras* request_extras = (ebb_request_extras*)request->data;
34+
if (request_extras->dispatcher)
35+
{
36+
}
1737
}
1838

19-
static void main_async_dispatch(EV_P_ ev_async* w, int revents)
39+
static void on_connection_response_continue(ebb_connection* connection)
2040
{
21-
dispatch_main();
41+
ebb_connection_schedule_close(connection);
2242
}
2343

24-
static void on_request_path(ebb_request* request, const char* at, size_t length)
44+
static void on_request_response(void* context)
2545
{
46+
ebb_request* request = (ebb_request*)context;
47+
ebb_request_extras* request_extras = (ebb_request_extras*)request->data;
48+
ebb_connection* connection = request_extras->connection;
49+
ebb_connection_write(connection, request_extras->response.data, request_extras->response.len, on_connection_response_continue);
50+
ccfree(request);
2651
}
2752

28-
static void on_request_query_string(ebb_request* request, const char* at, size_t length)
53+
static void on_request_processing(void* context)
2954
{
55+
// this is called off-thread
56+
ebb_request* request = (ebb_request*)context;
57+
ebb_request_extras* request_extras = (ebb_request_extras*)request->data;
58+
request_extras->response = request_extras->dispatcher->dispatch(0);
59+
dispatch_main_async_f(request, on_request_response);
3060
}
3161

3262
static void on_request_dispatch(ebb_request* request)
3363
{
34-
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
35-
// do the real computation off thread
36-
dispatch_main_async(^{
37-
});
38-
});
64+
ebb_request_extras* request_extras = (ebb_request_extras*)request->data;
65+
ebb_connection* connection = request_extras->connection;
66+
if (request_extras->dispatcher)
67+
dispatch_async_f(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), request, on_request_processing);
68+
else // write 404
69+
ebb_connection_write(connection, ebb_http_404, sizeof(ebb_http_404), on_connection_response_continue);
3970
}
4071

4172
static ebb_request* new_request(ebb_connection* connection)
4273
{
4374
ebb_request* request = (ebb_request*)ccmalloc(sizeof(ebb_request) + sizeof(ebb_request_extras));
4475
ebb_request_init(request);
76+
ebb_connection_extras* connection_extras = (ebb_connection_extras*)(connection->data);
77+
connection_extras->request = request;
4578
ebb_request_extras* request_extras = (ebb_request_extras*)(request + 1);
4679
request_extras->connection = connection;
4780
request->data = request_extras;
@@ -58,8 +91,11 @@ static void on_connection_close(ebb_connection* connection)
5891

5992
static ebb_connection* new_connection(ebb_server* server, struct sockaddr_in* addr)
6093
{
61-
ebb_connection* connection = (ebb_connection*)ccmalloc(sizeof(ebb_connection));
94+
ebb_connection* connection = (ebb_connection*)ccmalloc(sizeof(ebb_connection) + sizeof(ebb_connection_extras));
6295
ebb_connection_init(connection);
96+
ebb_connection_extras* connection_extras = (ebb_connection_extras*)(connection + 1);
97+
connection_extras->request = 0;
98+
connection->data = connection_extras;
6399
connection->new_request = new_request;
64100
connection->on_close = on_connection_close;
65101
return connection;
@@ -71,7 +107,10 @@ int main(int argc, char** argv)
71107
ebb_server_init(&server, EV_DEFAULT);
72108
server.new_connection = new_connection;
73109
ebb_server_listen_on_port(&server, 3350);
74-
ev_async_init(&main_async, main_async_dispatch);
110+
printf("Listen on 3350, http://localhost:3350/\n");
111+
main_async_init();
112+
main_async_start(EV_DEFAULT);
75113
ev_run(EV_DEFAULT_ 0);
114+
main_async_destroy();
76115
return 0;
77116
}

serve/uri.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include "uri.h"
2+
#include <string.h>
3+
4+
static const ccv_uri_dispatch_t uri_map[] = {
5+
{
6+
.uri = "/bbf/detect.objects",
7+
.dispatch = ebb_bbf_detect_objects,
8+
},
9+
};
10+
11+
12+
ccv_uri_dispatch_t* find_uri_dispatch(const char* path)
13+
{
14+
ccv_uri_dispatch_t* low = (ccv_uri_dispatch_t*)uri_map;
15+
ccv_uri_dispatch_t* high = (ccv_uri_dispatch_t*)uri_map + sizeof(uri_map) / sizeof(ccv_uri_dispatch_t) - 1;
16+
while (low <= high)
17+
{
18+
ccv_uri_dispatch_t* middle = low + (high - low) / 2;
19+
int flag = strcmp(middle->uri, path);
20+
if (flag == 0)
21+
return middle;
22+
else if (flag < 0)
23+
low = middle + 1;
24+
else
25+
high = middle - 1;
26+
}
27+
return 0;
28+
}

serve/uri.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#ifndef _GUARD_uri_h_
2+
#define _GUARD_uri_h_
3+
4+
#include "ebb.h"
5+
6+
typedef struct {
7+
char* uri;
8+
ebb_buf (*dispatch)(const void*);
9+
} ccv_uri_dispatch_t;
10+
11+
ccv_uri_dispatch_t* find_uri_dispatch(const char* path);
12+
ebb_buf ebb_bbf_detect_objects(const void* query);
13+
14+
#endif

test/functional/makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ include ../../lib/config.mk
22

33
#CC +=# -fprofile-arcs -ftest-coverage
44
LDFLAGS := -L"../../lib" -lccv $(LDFLAGS)
5-
CFLAGS := -O3 -msse2 -Wall -I"../../lib" -I"../" $(CFLAGS)
5+
CFLAGS := -O3 -Wall -I"../../lib" -I"../" $(CFLAGS)
66
TARGETS = algebra.tests util.tests numeric.tests basic.tests memory.tests io.tests transform.tests
77

88
test: all

0 commit comments

Comments
 (0)