~ubuntu-branches/ubuntu/natty/scons/natty

« back to all changes in this revision

Viewing changes to engine/SCons/Job.py

  • Committer: Bazaar Package Importer
  • Author(s): Michael Bienia
  • Date: 2007-12-08 20:01:12 UTC
  • mfrom: (0.2.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20071208200112-vqk3vh6hm31pqlxu
Tags: 0.97.0d20071203-1ubuntu1
* Merge from debian unstable, remaining changes:
  - Don't use os.system()+env to spawn tools, working around underquoting of
    the environment until a real fix is done upstream.
  - debian/control: Modify Maintainer value to match
    DebianMaintainerField spec.

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30
30
#
31
31
 
32
 
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Job.py 0.97.D001 2007/05/17 11:35:19 knight"
 
32
__revision__ = "src/engine/SCons/Job.py 2509 2007/12/03 20:20:38 broonie"
33
33
 
34
34
import SCons.compat
35
35
 
76
76
            signal.signal(signal.SIGINT, signal.SIG_IGN)
77
77
            raise
78
78
 
 
79
    def cleanup(self):
 
80
        self.job.cleanup()
 
81
 
79
82
class Serial:
80
83
    """This class is used to execute tasks in series, and is more efficient
81
84
    than Parallel, but is only appropriate for non-parallel builds. Only
122
125
 
123
126
            task.postprocess()
124
127
 
 
128
    def cleanup(self):
 
129
        pass
125
130
 
126
131
# Trap import failure so that everything in the Job module but the
127
132
# Parallel class (and its dependent classes) will work if the interpreter
148
153
            while 1:
149
154
                task = self.requestQueue.get()
150
155
 
 
156
                if not task:
 
157
                    # The "None" value is used as a sentinel by
 
158
                    # ThreadPool.cleanup().  This indicates that there
 
159
                    # are no more tasks, so we should quit.
 
160
                    break
 
161
 
151
162
                try:
152
163
                    task.execute()
153
164
                except KeyboardInterrupt:
170
181
            self.resultsQueue = Queue.Queue(0)
171
182
 
172
183
            # Create worker threads
 
184
            self.workers = []
173
185
            for _ in range(num):
174
 
                Worker(self.requestQueue, self.resultsQueue)
 
186
                worker = Worker(self.requestQueue, self.resultsQueue)
 
187
                self.workers.append(worker)
175
188
 
176
189
        def put(self, obj):
177
190
            """Put task into request queue."""
182
195
            return self.resultsQueue.get(block)
183
196
 
184
197
        def preparation_failed(self, obj):
185
 
            self.resultsQueue.put((obj, 0))
 
198
            self.resultsQueue.put((obj, False))
 
199
 
 
200
        def cleanup(self):
 
201
            """
 
202
            Shuts down the thread pool, giving each worker thread a
 
203
            chance to shut down gracefully.
 
204
            """
 
205
            # For each worker thread, put a sentinel "None" value
 
206
            # on the requestQueue (indicating that there's no work
 
207
            # to be done) so that each worker thread will get one and
 
208
            # terminate gracefully.
 
209
            for _ in self.workers:
 
210
                self.requestQueue.put(None)
 
211
 
 
212
            # Wait for all of the workers to terminate.
 
213
            # 
 
214
            # If we don't do this, later Python versions (2.4, 2.5) often
 
215
            # seem to raise exceptions during shutdown.  This happens
 
216
            # in requestQueue.get(), as an assertion failure that
 
217
            # requestQueue.not_full is notified while not acquired,
 
218
            # seemingly because the main thread has shut down (or is
 
219
            # in the process of doing so) while the workers are still
 
220
            # trying to pull sentinels off the requestQueue.
 
221
            #
 
222
            # Normally these terminations should happen fairly quickly,
 
223
            # but we'll stick a one-second timeout on here just in case
 
224
            # someone gets hung.
 
225
            for worker in self.workers:
 
226
                worker.join(1.0)
 
227
            self.workers = []
186
228
 
187
229
    class Parallel:
188
230
        """This class is used to execute tasks in parallel, and is somewhat 
261
303
 
262
304
                    if self.tp.resultsQueue.empty():
263
305
                        break
 
306
 
 
307
        def cleanup(self):
 
308
            self.tp.cleanup()