summaryrefslogtreecommitdiff
path: root/lldb/test/API/python_api/was_interrupted/interruptible.py
blob: 8a6b4e96f3eee005b2c3701867229e9ae08aac63 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import lldb
import threading

local_data = None

class BarrierContainer(threading.local):
    def __init__(self, before_interrupt_barrier, after_interrupt_barrier,  event):
        self.event = event
        self.before_interrupt_barrier = before_interrupt_barrier
        self.after_interrupt_barrier = after_interrupt_barrier

class WelcomeCommand(object):

    def __init__(self, debugger, session_dict):
        return

    def get_short_help(self):
        return "A command that waits for an interrupt before returning."

    def check_was_interrupted(self, debugger, use_interpreter):
        if use_interpreter:
            self.was_interrupted = debugger.GetCommandInterpreter().WasInterrupted()
        else:
            self.was_interrupted = debugger.InterruptRequested()
        if local_data.event:
            self.was_canceled = local_data.event.is_set()

    def __call__(self, debugger, args, exe_ctx, result):
        """Command arguments:
            {interp/debugger} - Whether to use SBCommandInterpreter::WasInterrupted
                                of SBDebugger::InterruptRequested().
            check - Don't do the rendevous, just check if an interrupt was requested.
                    If check is not provided, we'll do the lock and then check.
            poll  - Should we poll once after the rendevous or spin waiting for the
                    interruption to happen.

            For the interrupt cases, the command waits serially on the barriers
            passed to it in local data, giving the test runner a chance to set the
            interrupt.  Once the barriers are passed, it waits for the interrupt
            or the event.
            If it finds an interrupt, it returns "Command was interrupted". If it gets an
            event before seeing the interrupt it returns "Command was not interrupted."
            For the "poll" case, it waits on the rendevous, then checks once.
            For the "check" case, it doesn't wait, but just returns whether there was
            an interrupt in force or not."""
            
        if local_data == None:
            result.SetError("local data was not set.")
            result.SetStatus(lldb.eReturnStatusFailed)
            return

        use_interpreter = "interp" in args
        if not use_interpreter:
            if not "debugger" in args:
                result.SetError("Must pass either 'interp' or 'debugger'")
                result.SetStatus(lldb.eReturnStatusFailed)
                return
            
        self.was_interrupted = False
        self.was_canceled = False
        
        if "check" in args:
            self.check_was_interrupted(debugger, use_interpreter)
            if self.was_interrupted:
                result.Print("Command was interrupted")
            else:
                result.Print("Command was not interrupted")
        else:
            # Wait here to rendevous in the test before it sets the interrupt.
            local_data.before_interrupt_barrier.wait()
            # Now the test will set the interrupt, and we can continue:
            local_data.after_interrupt_barrier.wait()
            
            if "poll" in args:
                self.check_was_interrupted(debugger, use_interpreter)
            else:
                while not self.was_interrupted and not self.was_canceled:
                    self.check_was_interrupted(debugger, use_interpreter)

            if self.was_interrupted:
                result.Print("Command was interrupted")
            else:
                result.Print("Command was not interrupted")

            if self.was_canceled:
                result.Print("Command was canceled")
        result.SetStatus(lldb.eReturnStatusSuccessFinishResult)
        return True