timed_io.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package net
  2. import (
  3. "io"
  4. "net"
  5. "time"
  6. )
  7. var (
  8. emptyTime time.Time
  9. )
  10. type TimeOutReader struct {
  11. timeout int
  12. connection net.Conn
  13. worker io.Reader
  14. }
  15. func NewTimeOutReader(timeout int /* seconds */, connection net.Conn) *TimeOutReader {
  16. reader := &TimeOutReader{
  17. connection: connection,
  18. timeout: -100,
  19. }
  20. reader.SetTimeOut(timeout)
  21. return reader
  22. }
  23. func (reader *TimeOutReader) Read(p []byte) (int, error) {
  24. return reader.worker.Read(p)
  25. }
  26. func (reader *TimeOutReader) GetTimeOut() int {
  27. return reader.timeout
  28. }
  29. func (reader *TimeOutReader) SetTimeOut(value int) {
  30. if value == reader.timeout {
  31. return
  32. }
  33. reader.timeout = value
  34. if value > 0 {
  35. reader.worker = &timedReaderWorker{
  36. timeout: value,
  37. connection: reader.connection,
  38. }
  39. } else {
  40. reader.worker = &noOpReaderWorker{
  41. connection: reader.connection,
  42. }
  43. }
  44. }
  45. func (reader *TimeOutReader) Release() {
  46. reader.connection = nil
  47. reader.worker = nil
  48. }
  49. type timedReaderWorker struct {
  50. timeout int
  51. connection net.Conn
  52. }
  53. func (this *timedReaderWorker) Read(p []byte) (int, error) {
  54. deadline := time.Duration(this.timeout) * time.Second
  55. this.connection.SetReadDeadline(time.Now().Add(deadline))
  56. nBytes, err := this.connection.Read(p)
  57. this.connection.SetReadDeadline(emptyTime)
  58. return nBytes, err
  59. }
  60. type noOpReaderWorker struct {
  61. connection net.Conn
  62. }
  63. func (this *noOpReaderWorker) Read(p []byte) (int, error) {
  64. return this.connection.Read(p)
  65. }