mirror of
https://github.com/Drop-OSS/libtailscale.git
synced 2026-07-01 06:41:57 -04:00
libtailscale: make tailscale_listener pollable
Use a socketpair(2) and sendmsg/recvmsg to pass a connection fd from Go to C. This lets people write non-blocking C by polling on a tailscale_listener for when they should tailscale_accept. Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
This commit is contained in:
committed by
David Crawshaw
parent
42597d5fb7
commit
b0e2f4a4e4
+39
-16
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/tailscale/libtailscale/tsnetctest"
|
||||
)
|
||||
@@ -11,27 +12,49 @@ func TestConn(t *testing.T) {
|
||||
|
||||
// RunTestConn cleans up after itself, so there shouldn't be
|
||||
// anything left in the global maps.
|
||||
conns.mu.Lock()
|
||||
rem := len(conns.m)
|
||||
conns.mu.Unlock()
|
||||
|
||||
if rem > 0 {
|
||||
t.Fatalf("want no remaining tsnet_conn objects, got %d", rem)
|
||||
}
|
||||
|
||||
listeners.mu.Lock()
|
||||
rem = len(listeners.m)
|
||||
listeners.mu.Unlock()
|
||||
|
||||
if rem > 0 {
|
||||
t.Fatalf("want no remaining tsnet_listener objects, got %d", rem)
|
||||
}
|
||||
|
||||
servers.mu.Lock()
|
||||
rem = len(servers.m)
|
||||
rem := len(servers.m)
|
||||
servers.mu.Unlock()
|
||||
|
||||
if rem > 0 {
|
||||
t.Fatalf("want no remaining tsnet objects, got %d", rem)
|
||||
}
|
||||
|
||||
var remConns, remLns int
|
||||
|
||||
for i := 0; i < 50; i++ {
|
||||
conns.mu.Lock()
|
||||
remConns = len(conns.m)
|
||||
conns.mu.Unlock()
|
||||
|
||||
listeners.mu.Lock()
|
||||
remLns = len(listeners.m)
|
||||
listeners.mu.Unlock()
|
||||
|
||||
if remConns == 0 && remLns == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
// We are waiting for cleanup goroutines to finish.
|
||||
//
|
||||
// libtailscale closes one side of a socketpair and
|
||||
// then Go responds to the other side being unreadable
|
||||
// by closing the connections and listeners.
|
||||
//
|
||||
// This is inherently asynchronous.
|
||||
// Without ditching the standard close(2) and having our
|
||||
// own close functions.
|
||||
//
|
||||
// So we spin for a while
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
|
||||
if remConns > 0 {
|
||||
t.Errorf("want no remaining tsnet_conn objects, got %d", remConns)
|
||||
}
|
||||
|
||||
if remLns > 0 {
|
||||
t.Errorf("want no remaining tsnet_listener objects, got %d", remLns)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user