def init_mmap(self, mmap_filename, mmap_group, socket_filename): log("init_mmap(%s, %s, %s)", mmap_filename, mmap_group, socket_filename) from xpra.net.mmap_pipe import ( #pylint: disable=import-outside-toplevel init_client_mmap, write_mmap_token, DEFAULT_TOKEN_INDEX, DEFAULT_TOKEN_BYTES, ) #calculate size: root_w, root_h = self.get_root_size() #at least 256MB, or 8 fullscreen RGBX frames: mmap_size = max(512 * 1024 * 1024, root_w * root_h * 4 * 8) mmap_size = min(2048 * 1024 * 1024, mmap_size) self.mmap_enabled, self.mmap_delete, self.mmap, self.mmap_size, self.mmap_tempfile, self.mmap_filename = \ init_client_mmap(mmap_group, socket_filename, mmap_size, self.mmap_filename) if self.mmap_enabled: self.mmap_token = get_int_uuid() self.mmap_token_bytes = DEFAULT_TOKEN_BYTES self.mmap_token_index = self.mmap_size - DEFAULT_TOKEN_BYTES #self.mmap_token_index = DEFAULT_TOKEN_INDEX*2 #write the token twice: # once at the old default offset for older servers, # and at the offset we want to use with new servers for index in (DEFAULT_TOKEN_INDEX, self.mmap_token_index): write_mmap_token(self.mmap, self.mmap_token, index, self.mmap_token_bytes)
def parse_client_caps(self, c): self.mmap_client_namespace = c.boolget("mmap.namespace", False) sep = ["_", "."][self.mmap_client_namespace] def mmapattr(k): return "mmap%s%s" % (sep, k) mmap_filename = c.strget(mmapattr("file")) if not mmap_filename: return mmap_size = c.intget(mmapattr("size"), 0) log("client supplied mmap_file=%s", mmap_filename) mmap_token = c.intget(mmapattr("token")) log("mmap supported=%s, token=%s", self.supports_mmap, mmap_token) if self.mmap_filename: log("using global server specified mmap file path: '%s'", self.mmap_filename) mmap_filename = self.mmap_filename if not self.supports_mmap: log("client enabled mmap but mmap mode is not supported", mmap_filename) elif WIN32 and mmap_filename.startswith("/"): log("mmap_file '%s' is a unix path", mmap_filename) elif not os.path.exists(mmap_filename): log("mmap_file '%s' cannot be found!", mmap_filename) else: from xpra.net.mmap_pipe import init_server_mmap, read_mmap_token, write_mmap_token, DEFAULT_TOKEN_INDEX, DEFAULT_TOKEN_BYTES self.mmap, self.mmap_size = init_server_mmap(mmap_filename, mmap_size) log("found client mmap area: %s, %i bytes - min mmap size=%i", self.mmap, self.mmap_size, self.min_mmap_size) if self.mmap_size>0: index = c.intget(mmapattr("token_index"), DEFAULT_TOKEN_INDEX) count = c.intget(mmapattr("token_bytes"), DEFAULT_TOKEN_BYTES) v = read_mmap_token(self.mmap, index, count) log("mmap_token=%#x, verification=%#x", mmap_token, v) if v!=mmap_token: log.warn("Warning: mmap token verification failed, not using mmap area!") log.warn(" expected '%#x', found '%#x'", mmap_token, v) self.mmap.close() self.mmap = None self.mmap_size = 0 elif self.mmap_size<self.min_mmap_size: log.warn("Warning: client supplied mmap area is too small, discarding it") log.warn(" we need at least %iMB and this area is %iMB", self.min_mmap_size//1024//1024, self.mmap_size//1024//1024) self.mmap.close() self.mmap = None self.mmap_size = 0 else: from xpra.os_util import get_int_uuid self.mmap_client_token = get_int_uuid() self.mmap_client_token_bytes = DEFAULT_TOKEN_BYTES if c.intget("mmap_token_index"): #we can write the token anywhere we want and tell the client, #so write it right at the end: self.mmap_client_token_index = self.mmap_size-self.mmap_client_token_bytes else: #use the expected default for older versions: self.mmap_client_token_index = DEFAULT_TOKEN_INDEX write_mmap_token(self.mmap, self.mmap_client_token, self.mmap_client_token_index, self.mmap_client_token_bytes) if self.mmap_size>0: log.info(" mmap is enabled using %sB area in %s", std_unit(self.mmap_size, unit=1024), mmap_filename)