This is an automated email from the ASF dual-hosted git repository.

hsluoyz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/casbin-gateway.git

commit 216573a0b4f261f269b6c5b0756211d198e9656e
Author: Yang Luo <[email protected]>
AuthorDate: Fri Sep 4 22:41:25 2026 +0800

    fix(agents): terminate a timed-out hook instead of asking it to exit
---
 agenthook/exit_unix.go    | 25 +++++++++++++++++++++++++
 agenthook/exit_windows.go | 32 ++++++++++++++++++++++++++++++++
 agenthook/hook.go         |  2 +-
 3 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/agenthook/exit_unix.go b/agenthook/exit_unix.go
new file mode 100644
index 0000000..d45c956
--- /dev/null
+++ b/agenthook/exit_unix.go
@@ -0,0 +1,25 @@
+// Copyright 2026 The casbin Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//go:build !windows
+
+package agenthook
+
+import "os"
+
+// terminateSelf ends this process. Nothing unwinds a process on the way out
+// here, so the ordinary exit is already the immediate one.
+func terminateSelf() {
+       os.Exit(0)
+}
diff --git a/agenthook/exit_windows.go b/agenthook/exit_windows.go
new file mode 100644
index 0000000..3be36b0
--- /dev/null
+++ b/agenthook/exit_windows.go
@@ -0,0 +1,32 @@
+// Copyright 2026 The casbin Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package agenthook
+
+import (
+       "os"
+       "syscall"
+)
+
+// terminateSelf ends this process without unwinding it. os.Exit hands over to
+// the Windows loader, which a thread stuck there holds up for good: that is
+// how a hook whose event never arrives outlives its deadline by hours instead
+// of by nothing. There is nothing here to unwind - the hook writes no file and
+// holds no lock - so the deadline takes the process down outright.
+func terminateSelf() {
+       if handle, err := syscall.GetCurrentProcess(); err == nil {
+               _ = syscall.TerminateProcess(handle, 0)
+       }
+       os.Exit(0)
+}
diff --git a/agenthook/hook.go b/agenthook/hook.go
index 5586984..0950340 100644
--- a/agenthook/hook.go
+++ b/agenthook/hook.go
@@ -50,7 +50,7 @@ func ServeIfInvoked() {
        if len(os.Args) < 2 || os.Args[1] != Subcommand {
                return
        }
-       timer := time.AfterFunc(hookLifetime, func() { os.Exit(0) })
+       timer := time.AfterFunc(hookLifetime, terminateSelf)
        defer timer.Stop()
        _ = Run(os.Args[2:], os.Stdin, os.Stdout)
        os.Exit(0)


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to