From 66df5c58c999b92af900b7a382cb2a7025c4b66a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Thu, 17 Apr 2008 21:25:31 +0200 Subject: Enhanced get_use_desc - similar to the 'unify' branch --- portato/backend/portage/system.py | 84 +++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 39 deletions(-) diff --git a/portato/backend/portage/system.py b/portato/backend/portage/system.py index ef3feb9..a3583b1 100644 --- a/portato/backend/portage/system.py +++ b/portato/backend/portage/system.py @@ -3,17 +3,18 @@ # File: portato/backend/portage/system.py # This file is part of the Portato-Project, a graphical portage-frontend. # -# Copyright (C) 2006-2007 René 'Necoro' Neumann +# Copyright (C) 2006-2008 René 'Necoro' Neumann # This is free software. You may redistribute copies of it under the terms of # the GNU General Public License version 2. # There is NO WARRANTY, to the extent permitted by law. # # Written by René 'Necoro' Neumann -from __future__ import absolute_import +from __future__ import absolute_import, with_statement -import re, os +import re, os, os.path import portage +from collections import defaultdict from .package import PortagePackage from .settings import PortageSettings @@ -30,7 +31,10 @@ class PortageSystem (SystemInterface): def __init__ (self): """Constructor.""" self.settings = PortageSettings() - portage.WORLD_FILE = self.settings.settings["ROOT"]+portage.WORLD_FILE + portage.WORLD_FILE = os.path.join(self.settings.settings["ROOT"],portage.WORLD_FILE) + + self.use_descs = {} + self.local_use_descs = defaultdict(dict) def get_version (self): return "Portage %s" % portage.VERSION @@ -461,46 +465,48 @@ class PortageSystem (SystemInterface): check(p, True) return updating - - use_descs = {} - local_use_descs = {} + def get_use_desc (self, flag, package = None): # In the first run the dictionaries 'use_descs' and 'local_use_descs' are filled. # fill cache if needed - if self.use_descs == {} or self.local_use_descs == {}: - # read use.desc - fd = open(self.settings.settings["PORTDIR"]+"/profiles/use.desc") - lines = fd.readlines() - fd.close() - for line in lines: - line = line.strip() - if line != "" and line[0] != '#': - fields = [x.strip() for x in line.split(" - ",1)] - if len(fields) == 2: - self.use_descs[fields[0]] = fields[1] - - # read use.local.desc - fd = open(self.settings.settings["PORTDIR"]+"/profiles/use.local.desc") - lines = fd.readlines() - fd.close() - for line in lines: - line = line.strip() - if line != "" and line[0] != '#': - fields = [x.strip() for x in line.split(":",1)] - if len(fields) == 2: - if not fields[0] in self.local_use_descs: # create - self.local_use_descs[fields[0]] = {} - subfields = [x.strip() for x in fields[1].split(" - ",1)] - if len(subfields) == 2: - self.local_use_descs[fields[0]][subfields[0]] = subfields[1] + if not self.use_descs and not self.local_use_descs: + for dir in [self.settings.settings["PORTDIR"]] + self.settings.settings["PORTDIR_OVERLAY"].split(): + + # read use.desc + try: + f = open(os.path.join(dir, "profiles/use.desc")) + for line in f: + line = line.strip() + if line and line[0] != '#': + fields = [x.strip() for x in line.split(" - ",1)] + if len(fields) == 2: + self.use_descs[fields[0]] = fields[1] + except IOError: + pass + finally: + f.close() + + # read use.local.desc + try: + f = open(os.path.join(dir, "profiles/use.local.desc")) + for line in f: + line = line.strip() + if line and line[0] != '#': + fields = [x.strip() for x in line.split(":",1)] + if len(fields) == 2: + subfields = [x.strip() for x in fields[1].split(" - ",1)] + if len(subfields) == 2: + self.local_use_descs[fields[0]].update([subfields]) + except IOError: + pass + finally: + f.close() # start - desc = "" - if flag in self.use_descs: - desc = self.use_descs[flag] - if package != None: + desc = self.use_descs.get(flag, "") + if package is not None: if package in self.local_use_descs: - if flag in self.local_use_descs[package]: - desc = self.local_use_descs[package][flag] + desc = self.local_use_descs[package].get(flag, desc) + return desc -- cgit v1.2.3 From 34a06847d17454b33af17ef8a3b1bf8bd44817d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Thu, 17 Apr 2008 21:41:42 +0200 Subject: Changelog up2date --- doc/Changelog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/Changelog b/doc/Changelog index 8831fdd..2d16030 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -7,6 +7,8 @@ - now showing slots in the version list - added Turkish translation (thx to Gürkan Gür) - appended important version information to the exceptions +- also display useflag descriptions from overlays +- fixes lots of errors 0.9.0.3: - removed the "expanding bug" in 0.9.0.2 -- cgit v1.2.3 From 04f1ccf7b2c4c16d0d1b1fc975182b66964d055e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Fri, 18 Apr 2008 00:04:10 +0200 Subject: Only init dbus threads, if it is really needed. --- portato/plugins/dbus_init.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/portato/plugins/dbus_init.py b/portato/plugins/dbus_init.py index 851562c..653af31 100644 --- a/portato/plugins/dbus_init.py +++ b/portato/plugins/dbus_init.py @@ -1,4 +1,10 @@ -from dbus.mainloop.glib import threads_init +try: + from dbus.mainloop.glib import threads_init +except ImportError: + threads_init = None + +from portato.constants import USE_CATAPULT def dbus_init (*args): - threads_init() + if USE_CATAPULT and threads_init is not None: + threads_init() -- cgit v1.2.3 From e4f0e899d681aeb3577054644b032101e3cd2d16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Fri, 18 Apr 2008 00:53:14 +0200 Subject: Added seqizz' nick to the translators listings --- doc/TRANSLATORS | 2 +- portato/gui/templates/AboutWindow.glade | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/TRANSLATORS b/doc/TRANSLATORS index 131ddd6..8d5ca81 100644 --- a/doc/TRANSLATORS +++ b/doc/TRANSLATORS @@ -1,4 +1,4 @@ Catalan: Roger Calvó German: René 'Necoro' Neumann Polish: Tomasz Osiński -Turkish: Gürkan Gür +Turkish: Gürkan 'seqizz' Gür diff --git a/portato/gui/templates/AboutWindow.glade b/portato/gui/templates/AboutWindow.glade index 57708d9..fe041c4 100644 --- a/portato/gui/templates/AboutWindow.glade +++ b/portato/gui/templates/AboutWindow.glade @@ -28,7 +28,7 @@ Thanks goto: Catalan - Roger Calvó German - René 'Necoro' Neumann Polish - Tomasz Osiński -Turkish - Gürkan Gür +Turkish - Gürkan 'seqizz' Gür p4r4d0x (inspired by wolfden) -- cgit v1.2.3 From 4cc1e681aaec4accbc72f33f51677d9aded037cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Fri, 18 Apr 2008 01:55:15 +0200 Subject: Fixed update world to fit current portage handling --- portato/backend/portage/system.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/portato/backend/portage/system.py b/portato/backend/portage/system.py index a3583b1..10fa9bc 100644 --- a/portato/backend/portage/system.py +++ b/portato/backend/portage/system.py @@ -36,6 +36,8 @@ class PortageSystem (SystemInterface): self.use_descs = {} self.local_use_descs = defaultdict(dict) + self._version = tuple([x.split("_")[0] for x in portage.VERSION.split(".")]) + def get_version (self): return "Portage %s" % portage.VERSION @@ -155,7 +157,7 @@ class PortageSystem (SystemInterface): return PortagePackage(portage.best(list)) def find_best_match (self, search_key, masked = False, only_installed = False, only_cpv = False): - t = None + t = [] if not only_installed: try: @@ -173,11 +175,14 @@ class PortageSystem (SystemInterface): t += self.settings.porttree.dbapi.match(cp) else: raise - else: - t = self.find_installed_packages(search_key, masked, only_cpv = True) + + if self._version >= (2,1,5) or only_installed: + t += [pkg.get_cpv() for pkg in self.find_installed_packages(search_key) if not pkg.is_masked()] if t: + t = unique_array(t) return self.find_best(t, only_cpv) + return None def find_packages (self, search_key, masked=False, only_cpv = False): @@ -373,7 +378,7 @@ class PortageSystem (SystemInterface): # append system packages packages.extend(unique_array([p.get_cp() for p in self.find_all_system_packages()])) - states = [(["RDEPEND"], True)] + states = [(["RDEPEND", "PDEPEND"], True)] if self.with_bdeps(): states.append((["DEPEND"], True)) -- cgit v1.2.3 From 92443dcb6dd74e67899553ab58ce1a30560bd8dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Mon, 21 Apr 2008 23:10:37 +0200 Subject: Added shortcut for 'Reload Portage' - increased max. scrollback lines --- portato/gui/templates/MainWindow.glade | 194 +++++++++++++++++---------------- portato/gui/windows/main.py | 2 +- 2 files changed, 99 insertions(+), 97 deletions(-) diff --git a/portato/gui/templates/MainWindow.glade b/portato/gui/templates/MainWindow.glade index 7422126..788a339 100644 --- a/portato/gui/templates/MainWindow.glade +++ b/portato/gui/templates/MainWindow.glade @@ -1,6 +1,6 @@ - + 2 @@ -46,6 +46,8 @@ Re_load Portage True + + True @@ -614,271 +616,271 @@ - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True 0 - label + use flags + PANGO_ELLIPSIZE_END True 1 2 - 3 - 4 + 4 + 5 - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True 0 - <b>License:</b> + <b>Use Flags:</b> True True - 3 - 4 + 4 + 5 GTK_FILL 5 - + True + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True - <b>Installed, but not in portage anymore</b> - True + Testing + 0 + 0 + True + - 2 - 5 - 6 + 7 + 8 + GTK_FILL - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - <span foreground='red'><b>MISSING KEYWORD</b></span> - True + 0 + 1 2 - 5 - 6 + 8 + 9 - + True + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - - - + True + Masked + 0 + 0 + True + - 1 - 2 - 2 - 3 + 8 + 9 + GTK_FILL - + True + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + Installed 0 - <b>Description:</b> - True - True + 0 + True + + 6 + 7 GTK_FILL - 5 - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True 0 - <b>Overlay:</b> + <b>Homepage:</b> True True - 1 - 2 + 2 + 3 GTK_FILL 5 - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True 0 label - True + True 1 2 + 1 + 2 - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True 0 label - True + True 1 2 - 1 - 2 - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True 0 - <b>Homepage:</b> + <b>Overlay:</b> True True - 2 - 3 + 1 + 2 GTK_FILL 5 - + True - True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - Installed 0 - 0 - True - + <b>Description:</b> + True + True - 6 - 7 GTK_FILL + 5 - + True - True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - Masked - 0 - 0 - True - + 5 + + + - 8 - 9 - GTK_FILL + 1 + 2 + 2 + 3 - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 + True + <span foreground='red'><b>MISSING KEYWORD</b></span> + True - 1 2 - 8 - 9 + 5 + 6 - + True - True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True - Testing - 0 - 0 - True - + <b>Installed, but not in portage anymore</b> + True - 7 - 8 - GTK_FILL + 2 + 5 + 6 - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True 0 - <b>Use Flags:</b> + <b>License:</b> True True - 4 - 5 + 3 + 4 GTK_FILL 5 - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True 0 - use flags - PANGO_ELLIPSIZE_END + label True 1 2 - 4 - 5 + 3 + 4 diff --git a/portato/gui/windows/main.py b/portato/gui/windows/main.py index 99739ae..314a500 100644 --- a/portato/gui/windows/main.py +++ b/portato/gui/windows/main.py @@ -829,7 +829,7 @@ class MainWindow (Window): Builds the terminal. """ - self.console.set_scrollback_lines(1024) + self.console.set_scrollback_lines(2**30) self.console.set_scroll_on_output(True) self.console.set_font_from_string(self.cfg.get("consolefont", "GUI")) self.console.connect("button-press-event", self.cb_right_click) -- cgit v1.2.3 From 57fdab2f3e379d0e2ab7a3a394f3ff129f3efa34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Tue, 29 Apr 2008 19:13:24 +0200 Subject: Changed max scrollback lines to 2**20 to prevent segfaults --- portato/gui/windows/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/portato/gui/windows/main.py b/portato/gui/windows/main.py index 314a500..5dffad3 100644 --- a/portato/gui/windows/main.py +++ b/portato/gui/windows/main.py @@ -829,7 +829,7 @@ class MainWindow (Window): Builds the terminal. """ - self.console.set_scrollback_lines(2**30) + self.console.set_scrollback_lines(2**20) self.console.set_scroll_on_output(True) self.console.set_font_from_string(self.cfg.get("consolefont", "GUI")) self.console.connect("button-press-event", self.cb_right_click) -- cgit v1.2.3 From a28492883e6d11b79856a14b4da5d1074e42f99f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Thu, 1 May 2008 20:46:39 +0200 Subject: Fixed small bug --- portato/gui/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/portato/gui/utils.py b/portato/gui/utils.py index 151ec22..dc9b9f3 100644 --- a/portato/gui/utils.py +++ b/portato/gui/utils.py @@ -204,7 +204,7 @@ class Database (object): else: ninst = [] for pkg in self._db[cat]: - if pkg[2]: + if pkg.inst: yield pkg else: ninst.append(pkg) -- cgit v1.2.3 From 496036eaf6faac0f32e8d746f1d8b34f460cedb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Fri, 2 May 2008 01:37:50 +0200 Subject: Added pause systray icon --- icons/pausing.png | Bin 0 -> 3121 bytes icons/pausing.svg | 171 ++++++++++++++++++++++++++++++++++++++++++++ portato/gui/windows/main.py | 4 +- 3 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 icons/pausing.png create mode 100644 icons/pausing.svg diff --git a/icons/pausing.png b/icons/pausing.png new file mode 100644 index 0000000..af4bf6b Binary files /dev/null and b/icons/pausing.png differ diff --git a/icons/pausing.svg b/icons/pausing.svg new file mode 100644 index 0000000..0d8f05a --- /dev/null +++ b/icons/pausing.svg @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/portato/gui/windows/main.py b/portato/gui/windows/main.py index 5dffad3..88f95c4 100644 --- a/portato/gui/windows/main.py +++ b/portato/gui/windows/main.py @@ -25,7 +25,7 @@ from ...backend import flags, system # must be the first to avoid circular deps from ... import get_listener, plugin, dependency from ...helper import debug, warning, error, info, unique_array from ...session import Session -from ...constants import CONFIG_LOCATION, VERSION, APP_ICON +from ...constants import CONFIG_LOCATION, VERSION, APP_ICON, ICON_DIR from ...backend.exceptions import PackageNotFoundException, BlockedException # more GUI stuff @@ -1599,8 +1599,10 @@ class MainWindow (Window): self.emergePaused = cb.get_active() if not self.emergePaused: self.queue.continue_emerge() + self.tray.set_from_file(APP_ICON) else: self.queue.stop_emerge() + self.tray.set_from_file(os.path.join(ICON_DIR, "pausing.png")) # block the handlers of the other buttons # so that calling "set_active" does not call this callback recursivly -- cgit v1.2.3 From 287b37a3d437f5ebc44770819adbb5daca2d3449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Fri, 2 May 2008 15:05:39 +0200 Subject: Use only global shm --- portato.py | 8 +------- portato/plistener.py | 8 +------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/portato.py b/portato.py index 9a068ad..a4f871a 100755 --- a/portato.py +++ b/portato.py @@ -73,13 +73,7 @@ def main (): else: # start us again in root modus and launch listener - try: # local version - from _shm import shm_wrapper as shm - except ImportError: - try: # version installed together with portato - from portato._shm import shm_wrapper as shm - except ImportError: # the normal shm module - import shm_wrapper as shm + import shm_wrapper as shm mem = shm.create_memory(1024, permissions=0600) sig = shm.create_semaphore(InitialValue = 0, permissions = 0600) diff --git a/portato/plistener.py b/portato/plistener.py index 1a5197a..8d35ece 100644 --- a/portato/plistener.py +++ b/portato/plistener.py @@ -90,13 +90,7 @@ class PListener (object): self._sig = None self._rw = None else: - try: # local version - from _shm import shm_wrapper as shm - except ImportError: - try: # version installed together with portato - from portato._shm import shm_wrapper as shm - except ImportError: # the normal shm module - import shm_wrapper as shm + import shm_wrapper as shm self._mem = shm.SharedMemoryHandle(mem) self._sig = shm.SemaphoreHandle(sig) -- cgit v1.2.3 From 6ca8029d010c88be574d29cde8234d3dfb420d73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Fri, 2 May 2008 15:20:08 +0200 Subject: Removed _shm and now only use the one in portage; do not install catapult backend anymore --- _shm/__init__.py | 0 _shm/shm_wrapper.py | 302 ----------- _shm/shmmodule.c | 1409 --------------------------------------------------- setup.py | 116 +---- 4 files changed, 3 insertions(+), 1824 deletions(-) delete mode 100644 _shm/__init__.py delete mode 100644 _shm/shm_wrapper.py delete mode 100644 _shm/shmmodule.c diff --git a/_shm/__init__.py b/_shm/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/_shm/shm_wrapper.py b/_shm/shm_wrapper.py deleted file mode 100644 index 851f588..0000000 --- a/_shm/shm_wrapper.py +++ /dev/null @@ -1,302 +0,0 @@ -# shm_wrapper - A wrapper for the shm module which provides access -# to System V shared memory and semaphores on *nix systems. -# -# Copyright (c) 2007 by Philip Semanchuk -# Contact info at http://NikitaTheSpider.com/ -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -# Python modules -import random -import sys - -# Third party modules -import shm -from shm import error as shmerror - -r"""shm_wrapper - A wrapper for the shm module which provides access -to System V shared memory and semaphores on *nix systems. - -The module shm is a Python wrapper around system functions like shmget. This -module in turn offers higher-level, more Pythonic access to shared memory and -semaphores. - -Full documentation is online at http://NikitaTheSpider.com/python/shm/ - -""" - -def create_memory(size, permissions = 0666, InitCharacter = ' '): - """ Creates a new shared memory segment. One can destroy it either by calling the - module-level method remove_memory() or by calling the .remove() method of a handle to - said memory. - """ - memory = None - - # I create the memory using a randomly-generated key. I keep trying until I find one - # that works or until I hit an error. - while not memory: - key = random.randint(1, sys.maxint - 1) - try: - memory = shm.create_memory(key, size, permissions) - except shmerror, ExtraData: - if shm.memory_haskey(key): - # Oops, bad luck, the key exists. I'll try another. I can't call - # memory_haskey() before calling create_memory() because that would create - # a race condition where I could verify a key is not used but then another - # process could call create_memory() with that key before I got a chance to - # do so. - pass - else: - # Uh-oh, something fundamental is wrong. - raise shmerror, ExtraData - - # Here I implicitly discard the memory handle object returned to me by shm and instead - # return my own handle to the shared memory segment. - memory = SharedMemoryHandle(key) - - memory.write(InitCharacter[0] * memory.size) - - return memory - - -def remove_memory(key): - # Destroys the shared memory segment. Raises KeyError if the key doesn't exist. - shm.remove_memory(shm.getshmid(key)) - - -class SharedMemoryHandle(object): - def __init__(self, key): - self._MemoryHandle = None - - # getshmid will raise a KeyError if there's no memory segment with this key. - shmid = shm.getshmid(key) - self._MemoryHandle = shm.memory(shmid) - - - def __del__(self): - if self._MemoryHandle: - # This will raise an error if the memory has been destroyed. - try: - if self._MemoryHandle.attached: - self._MemoryHandle.detach() - except shmerror: - pass - - - def remove(self): - if self._MemoryHandle: - if self._MemoryHandle.attached: - self._MemoryHandle.detach() - - shm.remove_memory(self._MemoryHandle.shmid) - self._MemoryHandle = None - - - def read(self, NumberOfBytes = 0, offset = 0): - if not self._MemoryHandle.attached: - self._MemoryHandle.attach() - - if not NumberOfBytes: - NumberOfBytes = self._MemoryHandle.size - offset - - return self._MemoryHandle.read(NumberOfBytes, offset) - - - def write(self, s, offset = 0): - if not self._MemoryHandle.attached: - self._MemoryHandle.attach() - - self._MemoryHandle.write(s, offset) - - - # Properties start here ================================================================ - - # key - def __get_key(self): return self._MemoryHandle.key - def __set_key(self, foo): raise AttributeError - key = property(__get_key, __set_key) - - # size of segment - def __get_size(self): return self._MemoryHandle.size - def __set_size(self, foo): raise AttributeError - size = property(__get_size, __set_size) - - # permissions - def __get_permissions(self): return self._MemoryHandle.perm - def __set_permissions(self, permissions): self._MemoryHandle.setperm(permissions) - permissions = property(__get_permissions, __set_permissions) - - # The number of processes currently attached to this memory segment. - def __get_number_attached(self): return self._MemoryHandle.nattch - def __set_number_attached(self, foo): raise AttributeError - number_attached = property(__get_number_attached, __set_number_attached) - - # segment's uid - def __get_uid(self): return self._MemoryHandle.uid - def __set_uid(self, uid): self._MemoryHandle.setuid(uid) - uid = property(__get_uid, __set_uid) - - # segment's gid - def __get_gid(self): return self._MemoryHandle.gid - def __set_gid(self, gid): self._MemoryHandle.setgid(gid) - gid = property(__get_gid, __set_gid) - - # Creator uid (read-only) - def __get_creator_uid(self): return self._MemoryHandle.cuid - def __set_creator_uid(self, foo): raise AttributeError - creator_uid = property(__get_creator_uid, __set_creator_uid) - - # Creator gid (read-only) - def __get_creator_gid(self): return self._MemoryHandle.cgid - def __set_creator_gid(self, foo): raise AttributeError - creator_gid = property(__get_creator_gid, __set_creator_gid) - - # Creator pid (read-only) - def __get_creator_pid(self): return self._MemoryHandle.cpid - def __set_creator_pid(self, foo): raise AttributeError - creator_pid = property(__get_creator_pid, __set_creator_pid) - - # pid of last process to operate on this segment (read-only) - def __get_last_pid(self): return self._MemoryHandle.lpid - def __set_last_pid(self, foo): raise AttributeError - last_pid = property(__get_last_pid, __set_last_pid) - - - -def create_semaphore(InitialValue = 1, permissions = 0666): - """ Creates a new semaphore. One can destroy it either by calling the - module-level method remove_semaphore() or by calling the .remove() method of a - handle to said semaphore. - """ - semaphore = None - - # I create the semaphore using a randomly-generated key. I keep trying until I find one - # that works or until I hit an error. - while not semaphore: - key = random.randint(1, sys.maxint - 1) - try: - semaphore = shm.create_semaphore(key, InitialValue, permissions) - except shmerror, ExtraData: - if shm.semaphore_haskey(key): - # Oops, bad luck, the key exists. I'll try another. I can't call - # memory_haskey() before calling create_semaphore() because that would create - # a race condition where I could verify a key is not used but then another - # process could call create_semaphore() with that key before I got a chance to - # do so. - pass - else: - # Uh-oh, something fundamental is wrong. - raise ExtraData - - # Here I implicitly discard the semaphore object returned to me by shm and instead - # return my own handle to the semaphore. - return SemaphoreHandle(key) - - -def remove_semaphore(key): - # Destroys the semaphore. Raises KeyError if the key doesn't exist. - shm.remove_semaphore(shm.getsemid(key)) - - -class SemaphoreHandle(object): - def __init__(self, key): - # getsemid will raise a KeyError if appropriate. - self._SemaphoreHandle = shm.semaphore(shm.getsemid(key)) - - - def remove(self): - shm.remove_semaphore(self._SemaphoreHandle.semid) - self._SemaphoreHandle = None - - - def P(self): - # P = prolaag = probeer te verlagen (try to decrease) - self._SemaphoreHandle.P() - - - def V(self): - # V = verhoog (increase) - self._SemaphoreHandle.V() - - - def Z(self): - # Z = block until Zee semaphore is Zero - self._SemaphoreHandle.Z() - - - # Properties start here ================================================================ - def __get_key(self): return self._SemaphoreHandle.key - def __set_key(self, foo): raise AttributeError - key = property(__get_key, __set_key) - - - def __get_value(self): return self._SemaphoreHandle.val - def __set_value(self, value): self._semaphore.setval(value) - value = property(__get_value, __set_value) - - - def __get_WaitingForZero(self): return self._SemaphoreHandle.zcnt - def __set_WaitingForZero(self, foo): raise AttributeError - WaitingForZero = property(__get_WaitingForZero, __set_WaitingForZero) - - - def __get_WaitingForNonZero(self): return self._SemaphoreHandle.ncnt - def __set_WaitingForNonZero(self, foo): raise AttributeError - WaitingForNonZero = property(__get_WaitingForNonZero, __set_WaitingForNonZero) -