summaryrefslogtreecommitdiffhomepage
path: root/src/go
diff options
context:
space:
mode:
Diffstat (limited to 'src/go')
-rw-r--r--src/go/unit/request.go2
-rw-r--r--src/go/unit/unit.go49
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)