public
Description: Phusion Passenger (mod_rails)
Homepage: http://www.modrails.com/
Clone URL: git://github.com/FooBarWidget/passenger.git
Click here to lend your support to: passenger and make a donation at www.pledgie.com !
We can now run a DispatcherBucket 'hello world'
FooBarWidget (author)
Tue Jan 29 12:52:03 -0800 2008
commit  33c7093a0d205f9d9efda8843d38e25e899852e7
tree    b5204c34ffa45b5d53cc92d9274b8b0ec0c57b92
parent  31350b61f21358ea68084e49aa5167f2d26251bb
...
1
2
 
 
 
3
4
5
 
6
7
8
 
 
 
 
 
 
 
 
9
10
11
 
12
13
14
...
1
2
3
4
5
6
 
 
7
8
 
 
9
10
11
12
13
14
15
16
17
18
 
19
20
21
22
0
@@ -1,14 +1,22 @@
0
 APXS=apxs2
0
 APACHECTL=apache2ctl
0
+CXX=g++
0
+CXXFLAGS=-Wall -fPIC -g `pkg-config --cflags apr-util-1`
0
+OBJECTS=DispatcherBucket.o
0
 
0
-all:
0
- $(APXS) -c mod_rails.c
0
+.PHONY: all install clean start restart stop
0
 
0
-install:
0
- $(APXS) -i -c mod_rails.c
0
+all: $(OBJECTS)
0
+ CC=g++ $(APXS) -c mod_rails.c -Wc,DispatcherBucket.o -Wl,-lstdc++
0
+
0
+install: $(OBJECTS)
0
+ CC=g++ $(APXS) -i -c mod_rails.c -Wc,DispatcherBucket.o -Wl,-lstdc++
0
+
0
+DispatcherBucket.o: DispatcherBucket.cpp
0
+ $(CXX) $(CXXFLAGS) -c DispatcherBucket.cpp
0
 
0
 clean:
0
- rm -rf mod_rails.o mod_rails.lo mod_rails.slo mod_rails.la .libs
0
+ rm -rf *.o mod_rails.lo mod_rails.slo mod_rails.la .libs
0
 
0
 start:
0
   $(APACHECTL) start
...
1
2
 
 
 
3
4
5
...
35
36
37
 
38
39
40
41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
43
44
...
69
70
71
72
73
74
75
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
77
78
...
1
2
3
4
5
6
7
8
...
38
39
40
41
42
43
 
 
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
...
147
148
149
 
 
 
 
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
0
@@ -1,5 +1,8 @@
0
 #ifdef INSIDE_MOD_RAILS
0
 
0
+#include <unistd.h>
0
+#include "DispatcherBucket.h"
0
+
0
 static int
0
 file_exists(apr_pool_t *pool, const char *filename) {
0
   apr_finfo_t info;
0
@@ -35,10 +38,85 @@ verify_rails_dir(apr_pool_t *pool, const char *dir) {
0
   return file_exists(pool, apr_pstrcat(pool, dir, "/../config/environment.rb", NULL));
0
 }
0
 
0
+
0
 static int
0
 mod_rails_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *base_server) {
0
- ap_add_version_component(p, "mod_rails/" MOD_RAILS_VERSION);
0
- return OK;
0
+ pid_t pid;
0
+ int fds[2];
0
+
0
+ socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
0
+ pid = fork();
0
+ if (pid == 0) {
0
+ pid = fork();
0
+ if (pid == 0) {
0
+ char fd_string[20];
0
+
0
+ close(fds[0]);
0
+ apr_snprintf(fd_string, sizeof(fd_string), "%d", fds[1]);
0
+ execlp("ruby", "ruby", "/home/hongli/Projects/mod_rails/lib/mod_rails/spawn_manager.rb", fd_string, NULL);
0
+ _exit(1);
0
+ } else if (pid == -1) {
0
+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "mod_rails: Unable to fork a process: %s", strerror(errno));
0
+ _exit(0);
0
+ } else {
0
+ _exit(0);
0
+ }
0
+ } else if (pid == -1) {
0
+ close(fds[0]);
0
+ close(fds[1]);
0
+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "mod_rails: Unable to fork a process: %s", strerror(errno));
0
+ return DECLINED;
0
+ } else {
0
+ close(fds[1]);
0
+ waitpid(pid, NULL, 0);
0
+ ap_add_version_component(p, "mod_rails/" MOD_RAILS_VERSION);
0
+ return OK;
0
+ }
0
+}
0
+
0
+static void
0
+spawn_instance(int pipes[2]) {
0
+ int p1[2], p2[2];
0
+ pipe(p1);
0
+ pipe(p2);
0
+ pid_t pid = fork();
0
+ if (pid == 0) {
0
+ pid = fork();
0
+ if (pid == 0) {
0
+ dup2(p1[0], 0);
0
+ dup2(p2[1], 1);
0
+ close(p1[0]);
0
+ close(p1[1]);
0
+ close(p2[0]);
0
+ close(p2[1]);
0
+ execlp("ruby", "ruby", "/home/hongli/Projects/mod_rails/handler_demo.rb", NULL);
0
+ FILE *f;
0
+ _exit(0);
0
+ } else {
0
+ _exit(0);
0
+ }
0
+ } else {
0
+ close(p1[0]);
0
+ close(p2[1]);
0
+ waitpid(pid, NULL, 0);
0
+ pipes[0] = p2[0];
0
+ pipes[1] = p1[1];
0
+ }
0
+}
0
+
0
+static void
0
+debug(const char *format, ...) {
0
+ va_list ap;
0
+ char message[1024];
0
+
0
+ va_start(ap, format);
0
+ int size = apr_vsnprintf(message, sizeof(message), format, ap);
0
+ FILE *f = fopen("/dev/pts/2", "w");
0
+ if (f != NULL) {
0
+ fwrite(message, 1, size, f);
0
+ fclose(f);
0
+ }
0
+ va_end(ap);
0
 }
0
 
0
 static int
0
@@ -69,10 +147,29 @@ mod_rails_handle_request(request_rec *r) {
0
     return OK;
0
   }
0
   
0
- char message[1024];
0
- apr_snprintf(message, sizeof(message), "mod_rails: file=%s, uri=%s, root=%s", r->filename, r->uri, rails_dir);
0
- log_debug(APLOG_MARK, r, message);
0
- return DECLINED;
0
+ apr_bucket_brigade *bb;
0
+ apr_bucket *b;
0
+ int p[2];
0
+ uint16_t x;
0
+
0
+ bb = apr_brigade_create(r->connection->pool, r->connection->bucket_alloc);
0
+
0
+ spawn_instance(p);
0
+ x = 0;
0
+ write(p[1], &x, sizeof(x));
0
+ close(p[1]);
0
+ debug("hooks: %d, %d\n", p[0], p[1]);
0
+
0
+ b = dispatcher_bucket_create(r->pool, p[0], r->server->timeout, r->connection->bucket_alloc);
0
+ APR_BRIGADE_INSERT_TAIL(bb, b);
0
+
0
+ b = apr_bucket_eos_create(r->connection->bucket_alloc);
0
+ APR_BRIGADE_INSERT_TAIL(bb, b);
0
+
0
+ ap_scan_script_header_err_brigade(r, bb, NULL);
0
+ ap_pass_brigade(r->output_filters, bb);
0
+
0
+ return OK;
0
 }
0
 
0
 static int
...
3
4
5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
7
8
...
15
16
17
18
 
19
20
21
...
24
25
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
28
29
...
38
39
40
41
42
43
44
45
46
...
48
49
50
 
 
 
 
 
 
 
 
51
52
53
54
...
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
...
39
40
41
 
42
43
44
45
...
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
...
77
78
79
 
 
 
80
81
82
...
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
0
@@ -3,6 +3,30 @@
0
 module ModRails # :nodoc:
0
 
0
 class RequestHandler
0
+ class Messages
0
+ def self.read(io)
0
+ buffer = ''
0
+ while buffer.size < 2
0
+ buffer << io.readpartial(2 - buffer.size)
0
+ end
0
+ chunk_size = buffer.unpack('n')[0]
0
+ if chunk_size == 0
0
+ return nil
0
+ else
0
+ buffer = ''
0
+ while buffer.size < chunk_size
0
+ buffer << io.readpartial(chunk_size - buffer.size)
0
+ end
0
+ return buffer
0
+ end
0
+ end
0
+
0
+ def self.write(io, data)
0
+ io.write([data.size].pack('n') << data)
0
+ io.flush
0
+ end
0
+ end
0
+
0
   def initialize(reader_pipe, writer_pipe)
0
     @reader = reader_pipe
0
     @writer = writer_pipe
0
@@ -15,7 +39,7 @@ class RequestHandler
0
       done = false
0
       while !done
0
         begin
0
- puts "#{$$} received: " << @reader.readline
0
+ process_next_request
0
         rescue EOFError
0
           done = true
0
         end
0
@@ -24,6 +48,21 @@ class RequestHandler
0
       revert_signal_handlers
0
     end
0
   end
0
+
0
+ def process_next_request
0
+ done = false
0
+ chunk = read_chunk
0
+ while !chunk.nil?
0
+ chunk = read_chunk
0
+ end
0
+ content = "hello <b>world</b>!"
0
+ write_chunk("Status: 200 OK\r\n")
0
+ write_chunk("Content-Type: text/html\r\n")
0
+ write_chunk("Content-Length: #{content.size}\r\n")
0
+ write_chunk("\r\n")
0
+ write_chunk(content)
0
+ write_chunk("")
0
+ end
0
 
0
 private
0
   def reset_signal_handlers
0
@@ -38,9 +77,6 @@ private
0
       end
0
     end
0
     prev_handler = trap('HUP', 'IGNORE')
0
- if prev_handler != 'IGNORE'
0
- @previous_signal_handlers['HUP'] = prev_handler
0
- end
0
   end
0
   
0
   def revert_signal_handlers
0
@@ -48,6 +84,14 @@ private
0
       trap(signal, handler)
0
     end
0
   end
0
+
0
+ def read_chunk
0
+ return Messages.read(@reader)
0
+ end
0
+
0
+ def write_chunk(data)
0
+ Messages.write(@writer, data)
0
+ end
0
 end
0
 
0
 end # module ModRails
0
\ No newline at end of file
...
1
2
3
4
 
5
6
7
...
12
13
14
15
 
16
17
18
...
22
23
24
25
26
 
...
1
2
3
 
4
5
6
7
...
12
13
14
 
15
16
17
18
...
22
23
24
 
25
26
0
@@ -1,7 +1,7 @@
0
 class Object
0
   @@benchmark_results = {}
0
 
0
- def self.b!(name)
0
+ def b!(name)
0
     time1 = Time.now
0
     begin
0
       yield
0
@@ -12,7 +12,7 @@ class Object
0
     end
0
   end
0
   
0
- def self.benchmark_report
0
+ def benchmark_report
0
     total = 0
0
     @@benchmark_results.each_value do |time|
0
       total += time
0
@@ -22,4 +22,4 @@ class Object
0
     end
0
     printf "-- Total: %.4f\n", total
0
   end
0
-end
0
\ No newline at end of file
0
+end

Comments

    No one has commented yet.