summaryrefslogtreecommitdiffhomepage
path: root/src/go/unit/request.go
diff options
context:
space:
mode:
authorMax Romanov <max.romanov@nginx.com>2017-12-06 12:16:02 +0300
committerMax Romanov <max.romanov@nginx.com>2017-12-06 12:16:02 +0300
commitd14c0774c7e6f372dfebcfcafdcac718b7e28789 (patch)
tree6111a740fb2d1898b0375a8f65235d3f319b160a /src/go/unit/request.go
parent0db4d2531648796a3447a409f05bd82bcc91ff9f (diff)
downloadunit-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 '')
-rw-r--r--src/go/unit/request.go138
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)
}