github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/net/eventloop_windows.go (about) 1 // +build windows 2 3 package net 4 5 import ( 6 nt "net" 7 "time" 8 9 "github.com/angenalZZZ/gofunc/net/pool/bytebuffer" 10 ) 11 12 type eventloop struct { 13 ch chan interface{} // command channel 14 idx int // loop index 15 svr *server // server in loop 16 codec ICodec // codec for TCP 17 connCount int32 // number of active connections in event-loop 18 connections map[*stdConn]struct{} // track all the sockets bound to this loop 19 eventHandler EventHandler // user eventHandler 20 calibrateCallback func(*eventloop, int32) // callback func for re-adjusting connCount 21 } 22 23 func (el *eventloop) loopRun() { 24 var err error 25 defer func() { 26 if el.idx == 0 && el.svr.opts.Ticker { 27 close(el.svr.ticktock) 28 } 29 el.svr.signalShutdown(err) 30 el.svr.loopWG.Done() 31 el.loopEgress() 32 el.svr.loopWG.Done() 33 }() 34 if el.idx == 0 && el.svr.opts.Ticker { 35 go el.loopTicker() 36 } 37 for v := range el.ch { 38 switch v := v.(type) { 39 case error: 40 err = v 41 case *stdConn: 42 err = el.loopAccept(v) 43 case *tcpIn: 44 err = el.loopRead(v) 45 case *udpIn: 46 err = el.loopReadUDP(v.c) 47 case *stderr: 48 err = el.loopError(v.c, v.err) 49 case wakeReq: 50 err = el.loopWake(v.c) 51 case func() error: 52 err = v() 53 } 54 if err != nil { 55 el.svr.logger.Printf("event-loop:%d exits with error:%v\n", el.idx, err) 56 break 57 } 58 } 59 } 60 61 func (el *eventloop) loopAccept(c *stdConn) error { 62 el.connections[c] = struct{}{} 63 c.localAddr = el.svr.ln.lnaddr 64 c.remoteAddr = c.conn.RemoteAddr() 65 el.calibrateCallback(el, 1) 66 67 out, action := el.eventHandler.OnOpened(c) 68 if out != nil { 69 el.eventHandler.PreWrite() 70 _, _ = c.conn.Write(out) 71 } 72 if el.svr.opts.TCPKeepAlive > 0 { 73 if c, ok := c.conn.(*nt.TCPConn); ok { 74 _ = c.SetKeepAlive(true) 75 _ = c.SetKeepAlivePeriod(el.svr.opts.TCPKeepAlive) 76 } 77 } 78 return el.handleAction(c, action) 79 } 80 81 func (el *eventloop) loopRead(ti *tcpIn) (err error) { 82 c := ti.c 83 c.buffer = ti.in 84 85 for inFrame, _ := c.read(); inFrame != nil; inFrame, _ = c.read() { 86 out, action := el.eventHandler.React(inFrame, c) 87 if out != nil { 88 outFrame, _ := el.codec.Encode(c, out) 89 el.eventHandler.PreWrite() 90 _, err = c.conn.Write(outFrame) 91 } 92 switch action { 93 case None: 94 case Close: 95 return el.loopCloseConn(c) 96 case Shutdown: 97 return errServerShutdown 98 } 99 if err != nil { 100 return el.loopError(c, err) 101 } 102 } 103 _, _ = c.inboundBuffer.Write(c.buffer.Bytes()) 104 bytebuffer.Put(c.buffer) 105 c.buffer = nil 106 return 107 } 108 109 func (el *eventloop) loopCloseConn(c *stdConn) error { 110 return c.conn.SetReadDeadline(time.Now()) 111 } 112 113 func (el *eventloop) loopEgress() { 114 var closed bool 115 for v := range el.ch { 116 switch v := v.(type) { 117 case error: 118 if v == errCloseAllConns { 119 closed = true 120 for c := range el.connections { 121 _ = el.loopCloseConn(c) 122 } 123 } 124 case *stderr: 125 _ = el.loopError(v.c, v.err) 126 } 127 if closed && len(el.connections) == 0 { 128 break 129 } 130 } 131 } 132 133 func (el *eventloop) loopTicker() { 134 var ( 135 delay time.Duration 136 open bool 137 ) 138 for { 139 el.ch <- func() (err error) { 140 delay, action := el.eventHandler.Tick() 141 el.svr.ticktock <- delay 142 switch action { 143 case Shutdown: 144 err = errServerShutdown 145 } 146 return 147 } 148 if delay, open = <-el.svr.ticktock; open { 149 time.Sleep(delay) 150 } else { 151 break 152 } 153 } 154 } 155 156 func (el *eventloop) loopError(c *stdConn, err error) (e error) { 157 if e = c.conn.Close(); e == nil { 158 delete(el.connections, c) 159 el.calibrateCallback(el, -1) 160 switch el.eventHandler.OnClosed(c, err) { 161 case Shutdown: 162 return errServerShutdown 163 } 164 c.releaseTCP() 165 } else { 166 el.svr.logger.Printf("failed to close connection:%s, error:%v\n", c.remoteAddr.String(), e) 167 } 168 return 169 } 170 171 func (el *eventloop) loopWake(c *stdConn) error { 172 //if co, ok := el.connections[c]; !ok || co != c { 173 // return nil // ignore stale wakes. 174 //} 175 out, action := el.eventHandler.React(nil, c) 176 if out != nil { 177 frame, _ := el.codec.Encode(c, out) 178 _, _ = c.conn.Write(frame) 179 } 180 return el.handleAction(c, action) 181 } 182 183 func (el *eventloop) handleAction(c *stdConn, action Action) error { 184 switch action { 185 case None: 186 return nil 187 case Close: 188 return el.loopCloseConn(c) 189 case Shutdown: 190 return errServerShutdown 191 default: 192 return nil 193 } 194 } 195 196 func (el *eventloop) loopReadUDP(c *stdConn) error { 197 out, action := el.eventHandler.React(c.buffer.Bytes(), c) 198 if out != nil { 199 el.eventHandler.PreWrite() 200 _, _ = el.svr.ln.pconn.WriteTo(out, c.remoteAddr) 201 } 202 switch action { 203 case Shutdown: 204 return errServerShutdown 205 } 206 c.releaseUDP() 207 return nil 208 }