summaryrefslogtreecommitdiff
path: root/include_server/basics.py
diff options
context:
space:
mode:
Diffstat (limited to 'include_server/basics.py')
-rwxr-xr-xinclude_server/basics.py124
1 files changed, 69 insertions, 55 deletions
diff --git a/include_server/basics.py b/include_server/basics.py
index c23c7be..a0d7228 100755
--- a/include_server/basics.py
+++ b/include_server/basics.py
@@ -21,6 +21,7 @@
__author__ = 'Nils Klarlund'
+import glob
import os.path
import resource
import signal
@@ -28,69 +29,82 @@ import sys
import tempfile
-# MISCELLANEOUS CONSTANTS
+# TEMPORARY LOCATIONS FOR GENERATIONS OF COMPRESSED FILES
-# Place for creation of temporary directories.
-client_tmp = None
-# And, the current such temporary directory.
-client_root = None
-# This constant is embedded in names of client root directories.
-INCLUDE_SERVER_NAME = 'include_server'
+class ClientRootKeeper(object):
+ """Determine the tmp directory to use for compressed files.
+ Use the RAM disk-like /dev/shm as default place to store compressed files if
+ available. The protocol between the include server and distcc client
+ stipulates that the top three directories constitute the prefix prepended to
+ absolute file paths.
-def InitializeClientTmp():
- """Determine the tmp directory to use.
+ Instance vars:
+ client_tmp: a path, the place for creation of temporary directories.
+ client_root: a path, the current such temporary directory
- Use the RAM disk-like /dev/shm as default place to store compressed files if
- available.
+ A typical client root looks like:
+
+ - /tmp/tmpBDoZQV.include_server-6642-13/padding, or
+ - /dev/shm/tmpBDoZQV.include_server-6642-19
+
+ Note that each path has exactly three directory components to it. This is an
+ invariant. Some client roots are padded with '/padding' to satisfy the
+ invariant.
"""
+
+ # This constant is embedded in names of client root directories.
+ INCLUDE_SERVER_NAME = 'include_server'
- global client_tmp
- if 'DISTCC_CLIENT_TMP' in os.environ:
- client_tmp = os.environ['DISTCC_CLIENT_TMP']
- elif os.path.isdir('/dev/shm') and os.access('/dev/shm',
- os.X_OK + os.W_OK + os.R_OK):
- client_tmp = '/dev/shm'
- else:
- client_tmp = '/tmp'
- if not client_tmp or client_tmp[0] != '/':
- sys.exit("""DISTCC_CLIENT_TMP must start with '/'.""")
- client_tmp = client_tmp.rstrip('/')
- # The protocol between the include server and distcc client stipulates
- # that the top three directories constitute the prefix prepended to absolute
- # file paths. To have room to make a temp directory, we'll need to have less
- # than two levels at this point.
- # Note: '/a/b'.split('/') == ['', 'a', 'b'].
- if len(client_tmp.split('/')) > 3:
- sys.exit('DISTCC_CLIENT_TMP must have at most two directory levels.')
-
-
-def InitializeClientRoot(generation):
- """Make a client directory for a generation of compressed files.
+ def __init__(self):
+ """Constructor."""
+ if 'DISTCC_CLIENT_TMP' in os.environ:
+ self.client_tmp = os.environ['DISTCC_CLIENT_TMP']
+ elif os.path.isdir('/dev/shm') and os.access('/dev/shm',
+ os.X_OK + os.W_OK + os.R_OK):
+ self.client_tmp = '/dev/shm'
+ else:
+ self.client_tmp = '/tmp'
+ if not self.client_tmp or self.client_tmp[0] != '/':
+ sys.exit("""DISTCC_CLIENT_TMP must start with '/'.""")
+ self.client_tmp = self.client_tmp.rstrip('/')
+ # To have room to make a temp directory, we'll need to have less than two
+ # levels at this point. Note: '/a/b'.split('/') == ['', 'a', 'b'].
+ if len(self.client_tmp.split('/')) > 3:
+ sys.exit('DISTCC_CLIENT_TMP must have at most two directory levels.')
+ self.number_missing_levels = 3 - len(self.client_tmp.split('/'))
+ self.client_root = None
+
+ def Glob(self, pid_expr):
+ """Glob unpadded client roots whose pid is matched by pid expression."""
+ return glob.glob('%s/*.%s-%s-*'
+ % (self.client_tmp, self.INCLUDE_SERVER_NAME,
+ pid_expr))
- Arguments:
- generation: a natural number, usually 1 or slightly bigger; this number,
- minus 1, indicates how many times a reset of the caches has taken place.
- """
- assert client_tmp
- global client_root
- try:
- # Create a unique identifier that will never repeat. Use pid as suffix for
- # cleanout mechanism that wipes files not associated with a running pid.
- client_root = tempfile.mkdtemp('.%s-%s-%d' %
- (INCLUDE_SERVER_NAME,
- os.getpid(), generation),
- dir=client_tmp)
- number_missing_levels = 3 - len(client_tmp.split('/'))
- # Stuff client_root path until we have exactly three levels in all.
- for unused_i in range(number_missing_levels):
- client_root += '/padding'
- os.mkdir(client_root)
- except (IOError, OSError), why:
- sys.exit('Could not create client root directory %s: %s' %
- (client_root, why))
-
+ def ClientRootMakedir(self, generation):
+ """Make a new client directory for a generation of compressed files.
+
+ Arguments:
+ generation: a natural number, usually 1 or slightly bigger; this number,
+ minus 1, indicates how many times a reset of the caches has taken place.
+ """
+ try:
+ # Create a unique identifier that will never repeat. Use pid as suffix for
+ # cleanout mechanism that wipes files not associated with a running pid.
+ client_root_before_padding = tempfile.mkdtemp(
+ '.%s-%s-%d' %
+ (self.INCLUDE_SERVER_NAME,
+ os.getpid(), generation),
+ dir=self.client_tmp)
+ self.client_root = (client_root_before_padding
+ + '/padding' * self.number_missing_levels)
+ if not os.path.isdir(self.client_root):
+ os.makedirs(self.client_root)
+ except (IOError, OSError), why:
+ sys.exit('Could not create client root directory %s: %s' %
+ (self.client_root, why))
+
# For automated emails, see also src/emaillog.h.
DCC_EMAILLOG_WHOM_TO_BLAME = os.getenv('DISTCC_EMAILLOG_WHOM_TO_BLAME',