/util/mailslot.py

https://github.com/janschejbal/sabnzbd · Python · 130 lines · 69 code · 21 blank · 40 comment · 15 complexity · 34ac127bcb650f68d962ec229c378752 MD5 · raw file

  1. #!/usr/bin/python -OO
  2. # Copyright 2008-2011 The SABnzbd-Team <team@sabnzbd.org>
  3. #
  4. # This program is free software; you can redistribute it and/or
  5. # modify it under the terms of the GNU General Public License
  6. # as published by the Free Software Foundation; either version 2
  7. # of the License, or (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  17. """
  18. sabnzbd.mailslot - Mailslot communication
  19. """
  20. import os
  21. from win32file import GENERIC_WRITE, FILE_SHARE_READ, \
  22. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL
  23. from ctypes import c_uint, c_buffer, byref, sizeof, windll
  24. # Win32API Shortcuts
  25. CreateFile = windll.kernel32.CreateFileA
  26. ReadFile = windll.kernel32.ReadFile
  27. WriteFile = windll.kernel32.WriteFile
  28. CloseHandle = windll.kernel32.CloseHandle
  29. CreateMailslot = windll.kernel32.CreateMailslotA
  30. class MailSlot(object):
  31. """ Simple Windows Mailslot communication
  32. """
  33. slotname = r'mailslot\SABnzbd\ServiceSlot'
  34. def __init__(self):
  35. self.handle = -1
  36. def create(self, timeout):
  37. """ Create the Mailslot, after this only receiving is possible
  38. timeout is the read timeout used for receive calls.
  39. """
  40. slot = r'\\.\%s' % MailSlot.slotname
  41. self.handle = CreateMailslot(slot, 0, timeout, None)
  42. return self.handle != -1
  43. def connect(self):
  44. """ Connect to existing Mailslot so that writing is possible
  45. """
  46. slot = r'\\%s\%s' % (os.environ['COMPUTERNAME'], MailSlot.slotname)
  47. self.handle = CreateFile(slot, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
  48. return self.handle != -1
  49. def disconnect(self):
  50. """ Disconnect from Mailslot
  51. """
  52. if self.handle != -1:
  53. CloseHandle(self.handle)
  54. self.handle = -1
  55. return True
  56. def send(self, command):
  57. """ Send one message to Mailslot
  58. """
  59. if self.handle == -1:
  60. return False
  61. w = c_uint()
  62. return bool(WriteFile(self.handle, command, len(command), byref(w), 0))
  63. def receive(self):
  64. """ Receive one message from Mailslot
  65. """
  66. r = c_uint()
  67. buf = c_buffer(1024)
  68. if ReadFile(self.handle, buf, sizeof(buf), byref(r), 0):
  69. return buf.value
  70. else:
  71. return None
  72. #------------------------------------------------------------------------------
  73. # Simple test
  74. #
  75. # First start "mailslot.py server" in one process,
  76. # Then start "mailslot.py client" in another.
  77. # Five "restart" and one "stop" will be send from client to server.
  78. # The server will stop after receiving "stop"
  79. if __name__ == '__main__':
  80. import sys
  81. from time import sleep
  82. if not __debug__:
  83. print 'Run this test in non-optimized mode'
  84. exit(1)
  85. if len(sys.argv) > 1 and 'server' in sys.argv[1]:
  86. recv = MailSlot()
  87. ret = recv.create(2)
  88. assert ret, 'Failed to create'
  89. while True:
  90. data = recv.receive()
  91. if data is not None:
  92. print data
  93. if data.startswith('stop'):
  94. break
  95. sleep(2.0)
  96. recv.disconnect()
  97. elif len(sys.argv) > 1 and 'client' in sys.argv[1]:
  98. send = MailSlot()
  99. ret = send.connect()
  100. assert ret, 'Failed to connect'
  101. for n in xrange(5):
  102. ret = send.send('restart')
  103. assert ret, 'Failed to send'
  104. sleep(2.0)
  105. send.send('stop')
  106. assert ret, 'Failed to send'
  107. send.disconnect()
  108. else:
  109. print 'Usage: mailslot.py server|client'