~ubuntu-branches/ubuntu/vivid/python-gevent/vivid

« back to all changes in this revision

Viewing changes to gevent/greenlet.py

  • Committer: Bazaar Package Importer
  • Author(s): Örjan Persson
  • Date: 2011-05-17 16:43:20 UTC
  • mto: (14.1.1 sid)
  • mto: This revision was merged to the branch mainline in revision 7.
  • Revision ID: james.westby@ubuntu.com-20110517164320-jyr5vamkqi3jfeab
Tags: upstream-0.13.6
Import upstream version 0.13.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
import sys
4
4
import traceback
5
5
from gevent import core
6
 
from gevent.hub import greenlet, getcurrent, get_hub, GreenletExit, Waiter, kill
 
6
from gevent.hub import greenlet, getcurrent, get_hub, GreenletExit, Waiter
7
7
from gevent.timeout import Timeout
8
8
 
9
9
 
85
85
                error = LinkedCompleted(source)
86
86
        else:
87
87
            error = LinkedFailed(source)
88
 
        current = getcurrent()
89
 
        greenlet = self.greenlet
90
 
        if current is greenlet:
91
 
            greenlet.throw(error)
92
 
        elif current is get_hub():
93
 
            try:
94
 
                greenlet.throw(error)
95
 
            except:
96
 
                traceback.print_exc()
97
 
        else:
98
 
            kill(self.greenlet, error)
 
88
        self.greenlet.throw(error)
99
89
 
100
90
    def __hash__(self):
101
91
        return hash(self.greenlet)
139
129
class Greenlet(greenlet):
140
130
    """A light-weight cooperatively-scheduled execution unit."""
141
131
 
142
 
    args = ()
143
 
    kwargs = {}
144
 
 
145
132
    def __init__(self, run=None, *args, **kwargs):
146
133
        greenlet.__init__(self, parent=get_hub())
147
134
        if run is not None:
148
135
            self._run = run
149
 
        if args:
150
 
            self.args = args
151
 
        if kwargs:
152
 
            self.kwargs = kwargs
153
 
        self._links = set()
 
136
        self.args = args
 
137
        self.kwargs = kwargs
 
138
        self._links = []
154
139
        self.value = None
155
140
        self._exception = _NONE
156
141
        self._notifier = None
228
213
                # the result was not set and the links weren't notified. let's do it here.
229
214
                # checking that self.dead is true is essential, because the exception raised by
230
215
                # throw() could have been cancelled by the greenlet's function.
231
 
                if len(args)==1:
 
216
                if len(args) == 1:
232
217
                    arg = args[0]
233
218
                    #if isinstance(arg, type):
234
219
                    if type(arg) is type(Exception):
293
278
        If block is ``True`` (the default), wait until the greenlet dies or the optional timeout expires.
294
279
        If block is ``False``, the current greenlet is not unscheduled.
295
280
 
296
 
        The function always returns ``None`` and never raises an errir.
 
281
        The function always returns ``None`` and never raises an error.
297
282
 
298
283
        `Changed in version 0.13.0:` *block* is now ``True`` by default.
299
284
        """
304
289
            waiter = Waiter()
305
290
            core.active_event(_kill, self, exception, waiter)
306
291
            if block:
307
 
                waiter.wait()
 
292
                waiter.get()
308
293
                self.join(timeout)
309
294
        # it should be OK to use kill() in finally or kill a greenlet from more than one place;
310
295
        # thus it should not raise when the greenlet is already killed (= not started)
327
312
            try:
328
313
                t = Timeout.start_new(timeout)
329
314
                try:
330
 
                    result = get_hub().switch()
 
315
                    result = self.parent.switch()
331
316
                    assert result is self, 'Invalid switch into Greenlet.get(): %r' % (result, )
332
317
                finally:
333
318
                    t.cancel()
359
344
            try:
360
345
                t = Timeout.start_new(timeout)
361
346
                try:
362
 
                    result = get_hub().switch()
 
347
                    result = self.parent.switch()
363
348
                    assert result is self, 'Invalid switch into Greenlet.join(): %r' % (result, )
364
349
                finally:
365
350
                    t.cancel()
419
404
        """
420
405
        if not callable(callback):
421
406
            raise TypeError('Expected callable: %r' % (callback, ))
422
 
        self._links.add(callback)
 
407
        self._links.append(callback)
423
408
        if self.ready() and self._notifier is None:
424
409
            self._notifier = core.active_event(self._notify_links)
425
410
 
461
446
            receiver = getcurrent()
462
447
        # discarding greenlets when we have GreenletLink instances in _links works, because
463
448
        # a GreenletLink instance pretends to be a greenlet, hash-wise and eq-wise
464
 
        self._links.discard(receiver)
 
449
        try:
 
450
            self._links.remove(receiver)
 
451
        except ValueError:
 
452
            pass
465
453
 
466
454
    def link_value(self, receiver=None, GreenletLink=SuccessGreenletLink, SpawnedLink=SuccessSpawnedLink):
467
455
        """Like :meth:`link` but *receiver* is only notified when the greenlet has completed successfully"""
550
538
        if block:
551
539
            t = Timeout.start_new(timeout)
552
540
            try:
553
 
                alive = waiter.wait()
 
541
                alive = waiter.get()
554
542
                if alive:
555
543
                    joinall(alive, raise_error=False)
556
544
            finally:
614
602
 
615
603
 
616
604
_NONE = Exception("Neither exception nor value")
617