aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-09-27 19:46:35 +0900
committerOphestra <cat@gensokyo.uk>2025-09-27 19:46:35 +0900
commite906cae9ee0fd8b7b35c4a71af8ba86e60dd3c24 (patch)
tree71279c229d9ba92d6e239be0761d01586fa94021 /internal
parentae2df2c450dd655b93a950124b6ab16e2b4d967b (diff)
container/output: export suspendable writer
This is quite useful for other packages as well. This change prepares internal/hlog for removal. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal')
-rw-r--r--internal/hlog/hlog.go56
1 files changed, 2 insertions, 54 deletions
diff --git a/internal/hlog/hlog.go b/internal/hlog/hlog.go
index 415d16bf..ff9b201e 100644
--- a/internal/hlog/hlog.go
+++ b/internal/hlog/hlog.go
@@ -2,69 +2,17 @@
package hlog
import (
- "bytes"
- "io"
"log"
"os"
- "sync"
- "sync/atomic"
- "syscall"
-)
-const (
- bufSize = 4 * 1024
- bufSizeMax = 16 * 1024 * 1024
+ "hakurei.app/container"
)
-var o = &suspendable{w: os.Stderr}
+var o = &container.Suspendable{Downstream: os.Stderr}
// Prepare configures the system logger for [Suspend] and [Resume] to take effect.
func Prepare(prefix string) { log.SetPrefix(prefix + ": "); log.SetFlags(0); log.SetOutput(o) }
-type suspendable struct {
- w io.Writer
- s atomic.Bool
-
- buf bytes.Buffer
- bufOnce sync.Once
- bufMu sync.Mutex
- dropped int
-}
-
-func (s *suspendable) Write(p []byte) (n int, err error) {
- if !s.s.Load() {
- return s.w.Write(p)
- }
- s.bufOnce.Do(func() { s.prepareBuf() })
-
- s.bufMu.Lock()
- defer s.bufMu.Unlock()
-
- if l := len(p); s.buf.Len()+l > bufSizeMax {
- s.dropped += l
- return 0, syscall.ENOMEM
- }
- return s.buf.Write(p)
-}
-
-func (s *suspendable) prepareBuf() { s.buf.Grow(bufSize) }
-func (s *suspendable) Suspend() bool { return o.s.CompareAndSwap(false, true) }
-func (s *suspendable) Resume() (resumed bool, dropped uintptr, n int64, err error) {
- if o.s.CompareAndSwap(true, false) {
- o.bufMu.Lock()
- defer o.bufMu.Unlock()
-
- resumed = true
- dropped = uintptr(o.dropped)
-
- o.dropped = 0
- n, err = io.Copy(s.w, &s.buf)
- s.buf = bytes.Buffer{}
- s.prepareBuf()
- }
- return
-}
-
func Suspend() bool { return o.Suspend() }
func Resume() bool {
resumed, dropped, _, err := o.Resume()