1package util
2
3import (
4 "context"
5 "io"
6)
7
8type handleState struct {
9 handles []any
10 holes int
11}
12
13func (s *handleState) CloseNotify(ctx context.Context, exitCode uint32) {
14 for _, h := range s.handles {
15 if c, ok := h.(io.Closer); ok {
16 c.Close()
17 }
18 }
19 s.handles = nil
20 s.holes = 0
21}
22
23func GetHandle(ctx context.Context, id Ptr_t) any {
24 if id == 0 {
25 return nil
26 }
27 s := ctx.Value(moduleKey{}).(*moduleState)
28 return s.handles[^id]
29}
30
31func DelHandle(ctx context.Context, id Ptr_t) error {
32 if id == 0 {
33 return nil
34 }
35 s := ctx.Value(moduleKey{}).(*moduleState)
36 a := s.handles[^id]
37 s.handles[^id] = nil
38 if l := Ptr_t(len(s.handles)); l == ^id {
39 s.handles = s.handles[:l-1]
40 } else {
41 s.holes++
42 }
43 if c, ok := a.(io.Closer); ok {
44 return c.Close()
45 }
46 return nil
47}
48
49func AddHandle(ctx context.Context, a any) Ptr_t {
50 if a == nil {
51 panic(NilErr)
52 }
53
54 s := ctx.Value(moduleKey{}).(*moduleState)
55
56 // Find an empty slot.
57 if s.holes > cap(s.handles)-len(s.handles) {
58 for id, h := range s.handles {
59 if h == nil {
60 s.holes--
61 s.handles[id] = a
62 return ^Ptr_t(id)
63 }
64 }
65 }
66
67 // Add a new slot.
68 s.handles = append(s.handles, a)
69 return -Ptr_t(len(s.handles))
70}