timed_io.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  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 uint32
  12. connection net.Conn
  13. worker io.Reader
  14. }
  15. func NewTimeOutReader(timeout uint32 /* seconds */, connection net.Conn) *TimeOutReader {
  16. reader := &TimeOutReader{
  17. connection: connection,
  18. timeout: 0,
  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() uint32 {
  27. return reader.timeout
  28. }
  29. func (reader *TimeOutReader) SetTimeOut(value uint32) {
  30. if reader.worker != nil && 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. type timedReaderWorker struct {
  46. timeout uint32
  47. connection net.Conn
  48. }
  49. func (v *timedReaderWorker) Read(p []byte) (int, error) {
  50. deadline := time.Duration(v.timeout) * time.Second
  51. v.connection.SetReadDeadline(time.Now().Add(deadline))
  52. nBytes, err := v.connection.Read(p)
  53. v.connection.SetReadDeadline(emptyTime)
  54. return nBytes, err
  55. }
  56. type noOpReaderWorker struct {
  57. connection net.Conn
  58. }
  59. func (v *noOpReaderWorker) Read(p []byte) (int, error) {
  60. return v.connection.Read(p)
  61. }