@@ -54,7 +54,7 @@ def _destroy(self):
5454 num_clients = self ._rlist .client_count () - 2
5555 if num_clients == 0 and len (self ._rlist ) == 0 :
5656 # Free all resources associated with the mapped file
57- self ._manager ._fdict .pop (self ._rlist .path ())
57+ self ._manager ._fdict .pop (self ._rlist .path_or_fd ())
5858 #END remove regions list from manager
5959 #END handle regions
6060
@@ -190,7 +190,7 @@ def use_region(self, offset, size, flags = 0, _is_recursive=False):
190190 if man ._handle_count >= man ._max_handle_count :
191191 raise Exception
192192 #END assert own imposed max file handles
193- self ._region = self .MappedRegionCls (a .path (), mid .ofs , mid .size , flags )
193+ self ._region = self .MappedRegionCls (a .path_or_fd (), mid .ofs , mid .size , flags )
194194 except Exception :
195195 # apparently we are out of system resources or hit a limit
196196 # As many more operations are likely to fail in that condition (
@@ -278,9 +278,26 @@ def file_size(self):
278278 """:return: size of the underlying file"""
279279 return self ._rlist .file_size ()
280280
281+ def path_or_fd (self ):
282+ """:return: path or file decriptor of the underlying mapped file"""
283+ return self ._rlist .path_or_fd ()
284+
281285 def path (self ):
282- """:return: path of the underlying mapped file"""
283- return self ._rlist .path ()
286+ """:return: path of the underlying mapped file
287+ :raise ValueError: if attached path is not a path"""
288+ if isinstance (self ._rlist .path_or_fd (), int ):
289+ raise ValueError ("Path queried although mapping was applied to a file descriptor" )
290+ # END handle type
291+ return self ._rlist .path_or_fd ()
292+
293+ def fd (self ):
294+ """:return: file descriptor used to create the underlying mapping.
295+ :note: it is not required to be valid anymore
296+ :raise ValueError: if the mapping was not created by a file descriptor"""
297+ if isinstance (self ._rlist .path_or_fd (), basestring ):
298+ return ValueError ("File descriptor queried although mapping was generated from path" )
299+ #END handle type
300+ return self ._rlist .path_or_fd ()
284301
285302 #} END interface
286303
@@ -383,12 +400,18 @@ def _collect_lru_region(self, size):
383400 return num_found
384401
385402 #{ Interface
386- def make_cursor (self , path ):
387- """:return: a cursor pointing to the given path. It can be used to map new regions of the file into memory"""
388- regions = self ._fdict .get (path )
403+ def make_cursor (self , path_or_fd ):
404+ """:return: a cursor pointing to the given path or file descriptor.
405+ It can be used to map new regions of the file into memory
406+ :note: if a file descriptor is given, it is assumed to be open and valid,
407+ but may be closed afterwards. To refer to the same file, you may reuse
408+ your existing file descriptor, but keep in mind that new windows can only
409+ be mapped as long as it stays valid. This is why the using actual file paths
410+ are preferred unless you plan to keep the file descriptor open."""
411+ regions = self ._fdict .get (path_or_fd )
389412 if regions is None :
390- regions = self .MappedRegionListCls (path )
391- self ._fdict [path ] = regions
413+ regions = self .MappedRegionListCls (path_or_fd )
414+ self ._fdict [path_or_fd ] = regions
392415 # END obtain region for path
393416 return MemoryCursor (self , regions )
394417
0 commit comments