@@ -3,6 +3,7 @@ package p2pd
33import (
44 "context"
55 "fmt"
6+ "time"
67
78 "os"
89 "sync"
@@ -39,12 +40,28 @@ type Daemon struct {
3940 handlers map [protocol.ID ]ma.Multiaddr
4041 // closed is set when the daemon is shutting down
4142 closed bool
43+
44+ registeredUnaryProtocols map [protocol.ID ]bool
45+
46+ // callID (int64) to chan *pb.PersistentConnectionResponse
47+ // used to return responses to goroutines awating them
48+ responseWaiters sync.Map
49+ // callID (int64) to chan context.CancelFunc
50+ // used to cancel request handlers
51+ cancelUnary sync.Map
52+
53+ // this sync.Once ensures the goroutine awaiting deamon termination is
54+ // only run once
55+ terminateOnce sync.Once
56+ terminateWG sync.WaitGroup
57+ cancelTerminateTimer context.CancelFunc
4258}
4359
4460func NewDaemon (ctx context.Context , maddr ma.Multiaddr , dhtMode string , opts ... libp2p.Option ) (* Daemon , error ) {
4561 d := & Daemon {
46- ctx : ctx ,
47- handlers : make (map [protocol.ID ]ma.Multiaddr ),
62+ ctx : ctx ,
63+ handlers : make (map [protocol.ID ]ma.Multiaddr ),
64+ registeredUnaryProtocols : make (map [protocol.ID ]bool ),
4865 }
4966
5067 if dhtMode != "" {
@@ -71,7 +88,6 @@ func NewDaemon(ctx context.Context, maddr ma.Multiaddr, dhtMode string, opts ...
7188 }
7289 d .listener = l
7390
74- go d .listen ()
7591 go d .trapSignals ()
7692
7793 return d , nil
@@ -134,10 +150,10 @@ func (d *Daemon) Addrs() []ma.Multiaddr {
134150 return d .host .Addrs ()
135151}
136152
137- func (d * Daemon ) listen () {
153+ func (d * Daemon ) Serve () error {
138154 for {
139155 if d .isClosed () {
140- return
156+ return nil
141157 }
142158
143159 c , err := d .listener .Accept ()
@@ -191,3 +207,22 @@ func (d *Daemon) Close() error {
191207
192208 return merr .ErrorOrNil ()
193209}
210+
211+ func (d * Daemon ) awaitTermination () {
212+ d .terminateWG .Wait ()
213+ d .Close ()
214+ }
215+
216+ func (d * Daemon ) KillOnTimeout (timeout time.Duration ) {
217+ go func () {
218+ ctx , cancel := context .WithCancel (d .ctx )
219+ d .cancelTerminateTimer = cancel
220+
221+ select {
222+ case <- ctx .Done ():
223+ return
224+ case <- time .NewTimer (timeout ).C :
225+ d .Close ()
226+ }
227+ }()
228+ }
0 commit comments