diff options
Diffstat (limited to 'src/go/unit')
-rw-r--r-- | src/go/unit/request.go | 2 | ||||
-rw-r--r-- | src/go/unit/unit.go | 49 |
2 files changed, 49 insertions, 2 deletions
diff --git a/src/go/unit/request.go b/src/go/unit/request.go index ad56cabb..1d8c6702 100644 --- a/src/go/unit/request.go +++ b/src/go/unit/request.go @@ -135,7 +135,7 @@ func nxt_go_request_set_tls(go_req uintptr) { //export nxt_go_request_handler func nxt_go_request_handler(go_req uintptr, h uintptr) { r := get_request(go_req) - handler := *(*http.Handler)(unsafe.Pointer(h)) + handler := get_handler(h) go func(r *request) { handler.ServeHTTP(r.response(), &r.req) diff --git a/src/go/unit/unit.go b/src/go/unit/unit.go index 06257768..1534479e 100644 --- a/src/go/unit/unit.go +++ b/src/go/unit/unit.go @@ -13,6 +13,7 @@ import "C" import ( "fmt" "net/http" + "sync" "unsafe" ) @@ -87,12 +88,58 @@ func nxt_go_warn(format string, args ...interface{}) { C.nxt_cgo_warn(str_ref(str), C.uint32_t(len(str))) } +type handler_registry struct { + sync.RWMutex + next uintptr + m map[uintptr]*http.Handler +} + +var handler_registry_ handler_registry + +func set_handler(handler *http.Handler) uintptr { + + handler_registry_.Lock() + if handler_registry_.m == nil { + handler_registry_.m = make(map[uintptr]*http.Handler) + handler_registry_.next = 1 + } + + h := handler_registry_.next + handler_registry_.next += 1 + handler_registry_.m[h] = handler + + handler_registry_.Unlock() + + return h +} + +func get_handler(h uintptr) http.Handler { + handler_registry_.RLock() + defer handler_registry_.RUnlock() + + return *handler_registry_.m[h] +} + +func reset_handler(h uintptr) { + + handler_registry_.Lock() + if handler_registry_.m != nil { + delete(handler_registry_.m, h) + } + + handler_registry_.Unlock() +} + func ListenAndServe(addr string, handler http.Handler) error { if handler == nil { handler = http.DefaultServeMux } - rc := C.nxt_cgo_run(C.uintptr_t(uintptr(unsafe.Pointer(&handler)))) + h := set_handler(&handler) + + rc := C.nxt_cgo_run(C.uintptr_t(h)) + + reset_handler(h) if rc != 0 { return http.ListenAndServe(addr, handler) |