Exemple #1
0
            def __init__(self, name=None, create=False, size=0):
                if not size >= 0:
                    raise ValueError("'size' must be a positive integer")
                if create:
                    self._flags = _O_CREX | os.O_RDWR
                if name is None and not self._flags & os.O_EXCL:
                    raise ValueError("'name' can only be None if create=True")
                # Windows Named Shared Memory
                if create:
                    while True:
                        temp_name = _make_filename() if name is None else name
                        # Create and reserve shared memory block with this name
                        # until it can be attached to by mmap.
                        h_map = _winapi.CreateFileMapping(
                            _winapi.INVALID_HANDLE_VALUE, _winapi.NULL,
                            _winapi.PAGE_READWRITE, (size >> 32) & 0xFFFFFFFF,
                            size & 0xFFFFFFFF, temp_name)
                        try:
                            last_error_code = _winapi.GetLastError()
                            if last_error_code == _winapi.ERROR_ALREADY_EXISTS:
                                if name is not None:
                                    raise FileExistsError(
                                        errno.EEXIST,
                                        os.strerror(errno.EEXIST), name,
                                        _winapi.ERROR_ALREADY_EXISTS)
                                else:
                                    continue
                            self._mmap = mmap.mmap(-1, size, tagname=temp_name)
                        finally:
                            _winapi.CloseHandle(h_map)
                        self._name = temp_name
                        break

                else:
                    self._name = name
                    # Dynamically determine the existing named shared memory
                    # block's size which is likely a multiple of mmap.PAGESIZE.
                    h_map = _winapi.OpenFileMapping(_winapi.FILE_MAP_READ,
                                                    False, name)
                    try:
                        p_buf = _winapi.MapViewOfFile(h_map,
                                                      _winapi.FILE_MAP_READ, 0,
                                                      0, 0)
                    finally:
                        _winapi.CloseHandle(h_map)
                    size = _winapi.VirtualQuerySize(p_buf)
                    self._mmap = mmap.mmap(-1, size, tagname=name)

                self._size = size
                self._buf = memoryview(self._mmap)
    def __init__(self, name=None, create=False, size=0):
        if not size >= 0:
            raise ValueError("'size' must be a positive integer")
        if create:
            self._flags = _O_CREX | os.O_RDWR
            if size == 0:
                raise ValueError("'size' must be a positive number different from zero")
        if name is None and not self._flags & os.O_EXCL:
            raise ValueError("'name' can only be None if create=True")

        if _USE_POSIX:

            # POSIX Shared Memory

            if name is None:
                while True:
                    name = _make_filename()
                    try:
                        self._fd = _posixshmem.shm_open(
                            name,
                            self._flags,
                            mode=self._mode
                        )
                    except FileExistsError:
                        continue
                    self._name = name
                    break
            else:
                name = "/" + name if self._prepend_leading_slash else name
                self._fd = _posixshmem.shm_open(
                    name,
                    self._flags,
                    mode=self._mode
                )
                self._name = name
            try:
                if create and size:
                    os.ftruncate(self._fd, size)
                stats = os.fstat(self._fd)
                size = stats.st_size
                self._mmap = mmap.mmap(self._fd, size)
            except OSError:
                self.unlink()
                raise

            from .resource_tracker import register
            register(self._name, "shared_memory")

        else:

            # Windows Named Shared Memory

            if create:
                while True:
                    temp_name = _make_filename() if name is None else name
                    # Create and reserve shared memory block with this name
                    # until it can be attached to by mmap.
                    h_map = _winapi.CreateFileMapping(
                        _winapi.INVALID_HANDLE_VALUE,
                        _winapi.NULL,
                        _winapi.PAGE_READWRITE,
                        (size >> 32) & 0xFFFFFFFF,
                        size & 0xFFFFFFFF,
                        temp_name
                    )
                    try:
                        last_error_code = _winapi.GetLastError()
                        if last_error_code == _winapi.ERROR_ALREADY_EXISTS:
                            if name is not None:
                                raise FileExistsError(
                                    errno.EEXIST,
                                    os.strerror(errno.EEXIST),
                                    name,
                                    _winapi.ERROR_ALREADY_EXISTS
                                )
                            else:
                                continue
                        self._mmap = mmap.mmap(-1, size, tagname=temp_name)
                    finally:
                        _winapi.CloseHandle(h_map)
                    self._name = temp_name
                    break

            else:
                self._name = name
                # Dynamically determine the existing named shared memory
                # block's size which is likely a multiple of mmap.PAGESIZE.
                h_map = _winapi.OpenFileMapping(
                    _winapi.FILE_MAP_READ,
                    False,
                    name
                )
                try:
                    p_buf = _winapi.MapViewOfFile(
                        h_map,
                        _winapi.FILE_MAP_READ,
                        0,
                        0,
                        0
                    )
                finally:
                    _winapi.CloseHandle(h_map)
                size = _winapi.VirtualQuerySize(p_buf)
                self._mmap = mmap.mmap(-1, size, tagname=name)

        self._size = size
        self._buf = memoryview(self._mmap)
Exemple #3
0
    def __init__(self,
                 name: str = '',
                 size: int = 0,
                 readonly: bool = False,
                 mode: int = stat.S_IREAD | stat.S_IWRITE,
                 prefix: str = 'calibre-'):
        if size < 0:
            raise TypeError("'size' must be a non-negative integer")
        if size and name:
            raise TypeError('Cannot specify both name and size')
        if not name:
            flags = os.O_CREAT | os.O_EXCL
            if not size:
                raise TypeError("'size' must be > 0")
        else:
            flags = 0
        flags |= os.O_RDONLY if readonly else os.O_RDWR
        access = mmap.ACCESS_READ if readonly else mmap.ACCESS_WRITE

        create = not name
        tries = 30
        while not name and tries > 0:
            tries -= 1
            q = make_filename(prefix)
            if iswindows:
                h_map = _winapi.CreateFileMapping(
                    _winapi.INVALID_HANDLE_VALUE, _winapi.NULL,
                    _winapi.PAGE_READONLY
                    if readonly else _winapi.PAGE_READWRITE,
                    (size >> 32) & 0xFFFFFFFF, size & 0xFFFFFFFF, q)
                try:
                    last_error_code = _winapi.GetLastError()
                    if last_error_code == _winapi.ERROR_ALREADY_EXISTS:
                        continue
                    self._mmap = mmap.mmap(-1, size, tagname=q, access=access)
                    name = q
                finally:
                    _winapi.CloseHandle(h_map)
            else:
                try:
                    self._fd = _posixshmem.shm_open(q, flags, mode=mode)
                    name = q
                except FileExistsError:
                    continue
        if tries <= 0:
            raise OSError(
                f'Failed to create a uniquely named SHM file, try shortening the prefix from: {prefix}'
            )
        self._name = name

        if not create and iswindows:
            h_map = _winapi.OpenFileMapping(_winapi.FILE_MAP_READ, False, name)
            try:
                p_buf = _winapi.MapViewOfFile(h_map, _winapi.FILE_MAP_READ, 0,
                                              0, 0)
            finally:
                _winapi.CloseHandle(h_map)
            size = _winapi.VirtualQuerySize(p_buf)
            self._mmap = mmap.mmap(-1, size, tagname=name)
        if not iswindows:
            if not create:
                self._fd = _posixshmem.shm_open(name, flags, mode)
            try:
                if flags & os.O_CREAT and size:
                    os.ftruncate(self._fd, size)
                self.stats = os.fstat(self._fd)
                size = self.stats.st_size
                self._mmap = mmap.mmap(self._fd, size, access=access)
            except OSError:
                self.unlink()
                raise

        self._size = size