diff options
author | Max Romanov <max.romanov@nginx.com> | 2017-12-06 12:16:02 +0300 |
---|---|---|
committer | Max Romanov <max.romanov@nginx.com> | 2017-12-06 12:16:02 +0300 |
commit | d14c0774c7e6f372dfebcfcafdcac718b7e28789 (patch) | |
tree | 6111a740fb2d1898b0375a8f65235d3f319b160a /src/go/unit/request.go | |
parent | 0db4d2531648796a3447a409f05bd82bcc91ff9f (diff) | |
download | unit-d14c0774c7e6f372dfebcfcafdcac718b7e28789.tar.gz unit-d14c0774c7e6f372dfebcfcafdcac718b7e28789.tar.bz2 |
Go: removing request registry.
Passing unsafe.Pointers (void *) from Go to C is complicated by an attempt
to make such pointers less unsafe.
A straightforward optimization is to replace 'unsafe.Pointer' with 'uintptr'
(thanks to Xin Huang for the idea: https://stackoverflow.com/a/44826533 ).
As a result, request registry with mutex is gone.
Diffstat (limited to 'src/go/unit/request.go')
-rw-r--r-- | src/go/unit/request.go | 138 |
1 files changed, 20 insertions, 118 deletions
diff --git a/src/go/unit/request.go b/src/go/unit/request.go index 5af3db7b..4a839bdb 100644 --- a/src/go/unit/request.go +++ b/src/go/unit/request.go @@ -13,7 +13,7 @@ import "C" import ( "net/http" "net/url" - "sync" + "unsafe" ) type request struct { @@ -21,28 +21,14 @@ type request struct { resp *response c_req C.nxt_go_request_t id C.uint32_t - msgs []*cmsg - ch chan *cmsg } func (r *request) Read(p []byte) (n int, err error) { c := C.size_t(cap(p)) - b := C.malloc(c) - res := C.nxt_go_request_read(r.c_req, b, c) - - if res == -2 /* NXT_AGAIN */ { - m := <-r.ch + b := C.uintptr_t(uintptr(unsafe.Pointer(&p[0]))) - res = C.nxt_go_request_read_from(r.c_req, b, c, m.buf.b, - m.buf.s) - r.push(m) - } - - if res > 0 { - copy(p, C.GoBytes(b, res)) - } + res := C.nxt_go_request_read(r.c_req, b, c) - C.free(b) return int(res), nil } @@ -51,53 +37,6 @@ func (r *request) Close() error { return nil } -type request_registry struct { - sync.RWMutex - m map[C.nxt_go_request_t]*request - id map[C.uint32_t]*request -} - -var request_registry_ request_registry - -func find_request(c_req C.nxt_go_request_t) *request { - request_registry_.RLock() - res := request_registry_.m[c_req] - request_registry_.RUnlock() - - return res -} - -func find_request_by_id(id C.uint32_t) *request { - request_registry_.RLock() - res := request_registry_.id[id] - request_registry_.RUnlock() - - return res -} - -func add_request(r *request) { - request_registry_.Lock() - if request_registry_.m == nil { - request_registry_.m = make(map[C.nxt_go_request_t]*request) - request_registry_.id = make(map[C.uint32_t]*request) - } - - request_registry_.m[r.c_req] = r - request_registry_.id[r.id] = r - - request_registry_.Unlock() -} - -func remove_request(r *request) { - request_registry_.Lock() - if request_registry_.m != nil { - delete(request_registry_.m, r.c_req) - delete(request_registry_.id, r.id) - } - - request_registry_.Unlock() -} - func (r *request) response() *response { if r.resp == nil { r.resp = new_response(r.c_req, &r.req) @@ -107,33 +46,23 @@ func (r *request) response() *response { } func (r *request) done() { - remove_request(r) - C.nxt_go_request_done(r.c_req) - - for _, m := range r.msgs { - m.Close() - } - - if r.ch != nil { - close(r.ch) - } } -func (r *request) push(m *cmsg) { - r.msgs = append(r.msgs, m) +func get_request(go_req C.nxt_go_request_t) *request { + return (*request)(unsafe.Pointer(uintptr(go_req))) } //export nxt_go_new_request func nxt_go_new_request(c_req C.nxt_go_request_t, id C.uint32_t, - c_method *C.nxt_go_str_t, c_uri *C.nxt_go_str_t) { + c_method *C.nxt_go_str_t, c_uri *C.nxt_go_str_t) uintptr { uri := C.GoStringN(c_uri.start, c_uri.length) var URL *url.URL var err error if URL, err = url.ParseRequestURI(uri); err != nil { - return + return 0 } r := &request{ @@ -146,76 +75,49 @@ func nxt_go_new_request(c_req C.nxt_go_request_t, id C.uint32_t, }, c_req: c_req, id: id, - msgs: make([]*cmsg, 0, 1), } r.req.Body = r - add_request(r) -} - -//export nxt_go_find_request -func nxt_go_find_request(id C.uint32_t) C.nxt_go_request_t { - r := find_request_by_id(id) - - if r != nil { - return r.c_req - } - - return 0 + return uintptr(unsafe.Pointer(r)) } //export nxt_go_request_set_proto -func nxt_go_request_set_proto(c_req C.nxt_go_request_t, proto *C.nxt_go_str_t, +func nxt_go_request_set_proto(go_req C.nxt_go_request_t, proto *C.nxt_go_str_t, maj C.int, min C.int) { - r := find_request(c_req) + r := get_request(go_req) r.req.Proto = C.GoStringN(proto.start, proto.length) r.req.ProtoMajor = int(maj) r.req.ProtoMinor = int(min) } //export nxt_go_request_add_header -func nxt_go_request_add_header(c_req C.nxt_go_request_t, name *C.nxt_go_str_t, +func nxt_go_request_add_header(go_req C.nxt_go_request_t, name *C.nxt_go_str_t, value *C.nxt_go_str_t) { - r := find_request(c_req) + r := get_request(go_req) r.req.Header.Add(C.GoStringN(name.start, name.length), C.GoStringN(value.start, value.length)) } //export nxt_go_request_set_content_length -func nxt_go_request_set_content_length(c_req C.nxt_go_request_t, l C.int64_t) { - find_request(c_req).req.ContentLength = int64(l) -} - -//export nxt_go_request_create_channel -func nxt_go_request_create_channel(c_req C.nxt_go_request_t) { - find_request(c_req).ch = make(chan *cmsg) +func nxt_go_request_set_content_length(go_req C.nxt_go_request_t, l C.int64_t) { + get_request(go_req).req.ContentLength = int64(l) } //export nxt_go_request_set_host -func nxt_go_request_set_host(c_req C.nxt_go_request_t, host *C.nxt_go_str_t) { - find_request(c_req).req.Host = C.GoStringN(host.start, host.length) +func nxt_go_request_set_host(go_req C.nxt_go_request_t, host *C.nxt_go_str_t) { + get_request(go_req).req.Host = C.GoStringN(host.start, host.length) } //export nxt_go_request_set_url -func nxt_go_request_set_url(c_req C.nxt_go_request_t, scheme *C.char) { - find_request(c_req).req.URL.Scheme = C.GoString(scheme) +func nxt_go_request_set_url(go_req C.nxt_go_request_t, scheme *C.char) { + get_request(go_req).req.URL.Scheme = C.GoString(scheme) } //export nxt_go_request_set_remote_addr -func nxt_go_request_set_remote_addr(c_req C.nxt_go_request_t, +func nxt_go_request_set_remote_addr(go_req C.nxt_go_request_t, addr *C.nxt_go_str_t) { - find_request(c_req).req.RemoteAddr = C.GoStringN(addr.start, addr.length) -} - -//export nxt_go_request_serve -func nxt_go_request_serve(c_req C.nxt_go_request_t) { - r := find_request(c_req) - - go func(r *request) { - http.DefaultServeMux.ServeHTTP(r.response(), &r.req) - r.done() - }(r) + get_request(go_req).req.RemoteAddr = C.GoStringN(addr.start, addr.length) } |