mlock.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. # -*- coding: utf-8 -*-
  2. """
  3. # mlock support
  4. # Copyright (c) 2019-2024 Michael Büsch <m@bues.ch>
  5. # Licensed under the GNU/GPL version 2 or later.
  6. """
  7. import platform
  8. import os
  9. import sys
  10. __all__ = [
  11. "MLockWrapper",
  12. ]
  13. class MLockWrapper:
  14. """OS mlock wrapper.
  15. """
  16. __singleton = None
  17. @classmethod
  18. def get(cls):
  19. if cls.__singleton is None:
  20. cls.__singleton = cls()
  21. return cls.__singleton
  22. def __init__(self):
  23. self.__ffi = None
  24. self.__linux_libc = None
  25. isLinux = os.name == "posix" and "linux" in sys.platform.lower()
  26. isWindows = os.name == "nt" and "win32" in sys.platform.lower()
  27. if isLinux:
  28. try:
  29. from cffi import FFI
  30. except ImportError as e:
  31. print("Failed to import CFFI: %s\n"
  32. "Cannot use mlock() via CFFI.\n"
  33. "You might want to install CFFI by running: "
  34. "pip3 install cffi" % (
  35. str(e)), file=sys.stderr)
  36. return
  37. self.__ffi = FFI()
  38. # Use getattr to avoid Cython cdef compile error.
  39. getattr(self.__ffi, "cdef")("int mlockall(int flags);")
  40. self.__linux_libc = self.__ffi.dlopen(None)
  41. elif isWindows:
  42. pass # TODO
  43. else:
  44. pass # Unsupported OS.
  45. def mlockall(self):
  46. """Lock all current and all future memory.
  47. """
  48. error = "mlockall() is not supported on this operating system."
  49. if self.__linux_libc is not None and self.__ffi is not None:
  50. if platform.machine().lower() in (
  51. "alpha",
  52. "ppc", "ppc64", "ppcle", "ppc64le",
  53. "sparc", "sparc64" ):
  54. MCL_CURRENT = 0x2000
  55. MCL_FUTURE = 0x4000
  56. else:
  57. MCL_CURRENT = 0x1
  58. MCL_FUTURE = 0x2
  59. ret = self.__linux_libc.mlockall(MCL_CURRENT | MCL_FUTURE)
  60. error = os.strerror(self.__ffi.errno) if ret else ""
  61. return error