mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-29 19:52:24 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			70 lines
		
	
	
	
		
			1.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			70 lines
		
	
	
	
		
			1.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package util
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"io"
 | |
| )
 | |
| 
 | |
| type handleState struct {
 | |
| 	handles []any
 | |
| 	holes   int
 | |
| }
 | |
| 
 | |
| func (s *handleState) CloseNotify(ctx context.Context, exitCode uint32) {
 | |
| 	for _, h := range s.handles {
 | |
| 		if c, ok := h.(io.Closer); ok {
 | |
| 			c.Close()
 | |
| 		}
 | |
| 	}
 | |
| 	s.handles = nil
 | |
| 	s.holes = 0
 | |
| }
 | |
| 
 | |
| func GetHandle(ctx context.Context, id uint32) any {
 | |
| 	if id == 0 {
 | |
| 		return nil
 | |
| 	}
 | |
| 	s := ctx.Value(moduleKey{}).(*moduleState)
 | |
| 	return s.handles[^id]
 | |
| }
 | |
| 
 | |
| func DelHandle(ctx context.Context, id uint32) error {
 | |
| 	if id == 0 {
 | |
| 		return nil
 | |
| 	}
 | |
| 	s := ctx.Value(moduleKey{}).(*moduleState)
 | |
| 	a := s.handles[^id]
 | |
| 	s.handles[^id] = nil
 | |
| 	if l := uint32(len(s.handles)); l == ^id {
 | |
| 		s.handles = s.handles[:l-1]
 | |
| 	} else {
 | |
| 		s.holes++
 | |
| 	}
 | |
| 	if c, ok := a.(io.Closer); ok {
 | |
| 		return c.Close()
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func AddHandle(ctx context.Context, a any) uint32 {
 | |
| 	if a == nil {
 | |
| 		panic(NilErr)
 | |
| 	}
 | |
| 
 | |
| 	s := ctx.Value(moduleKey{}).(*moduleState)
 | |
| 
 | |
| 	// Find an empty slot.
 | |
| 	if s.holes > cap(s.handles)-len(s.handles) {
 | |
| 		for id, h := range s.handles {
 | |
| 			if h == nil {
 | |
| 				s.holes--
 | |
| 				s.handles[id] = a
 | |
| 				return ^uint32(id)
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// Add a new slot.
 | |
| 	s.handles = append(s.handles, a)
 | |
| 	return -uint32(len(s.handles))
 | |
| }
 |