summaryrefslogtreecommitdiff
path: root/libgo/go/exp/ogle/event.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/exp/ogle/event.go')
-rw-r--r--libgo/go/exp/ogle/event.go280
1 files changed, 0 insertions, 280 deletions
diff --git a/libgo/go/exp/ogle/event.go b/libgo/go/exp/ogle/event.go
deleted file mode 100644
index d7092ded336..00000000000
--- a/libgo/go/exp/ogle/event.go
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ogle
-
-import (
- "debug/proc"
- "fmt"
- "os"
-)
-
-/*
- * Hooks and events
- */
-
-// An EventHandler is a function that takes an event and returns a
-// response to that event and possibly an error. If an event handler
-// returns an error, the process stops and no other handlers for that
-// event are executed.
-type EventHandler func(e Event) (EventAction, os.Error)
-
-// An EventAction is an event handler's response to an event. If all
-// of an event's handlers execute without returning errors, their
-// results are combined as follows: If any handler returned
-// EAContinue, then the process resumes (without returning from
-// WaitStop); otherwise, if any handler returned EAStop, the process
-// remains stopped; otherwise, if all handlers returned EADefault, the
-// process resumes. A handler may return EARemoveSelf bit-wise or'd
-// with any other action to indicate that the handler should be
-// removed from the hook.
-type EventAction int
-
-const (
- EARemoveSelf EventAction = 0x100
- EADefault EventAction = iota
- EAStop
- EAContinue
-)
-
-// A EventHook allows event handlers to be added and removed.
-type EventHook interface {
- AddHandler(EventHandler)
- RemoveHandler(EventHandler)
- NumHandler() int
- handle(e Event) (EventAction, os.Error)
- String() string
-}
-
-// EventHook is almost, but not quite, suitable for user-defined
-// events. If we want user-defined events, make EventHook a struct,
-// special-case adding and removing handlers in breakpoint hooks, and
-// provide a public interface for posting events to hooks.
-
-type Event interface {
- Process() *Process
- Goroutine() *Goroutine
- String() string
-}
-
-type commonHook struct {
- // Head of handler chain
- head *handler
- // Number of non-internal handlers
- len int
-}
-
-type handler struct {
- eh EventHandler
- // True if this handler must be run before user-defined
- // handlers in order to ensure correctness.
- internal bool
- // True if this handler has been removed from the chain.
- removed bool
- next *handler
-}
-
-func (h *commonHook) AddHandler(eh EventHandler) {
- h.addHandler(eh, false)
-}
-
-func (h *commonHook) addHandler(eh EventHandler, internal bool) {
- // Ensure uniqueness of handlers
- h.RemoveHandler(eh)
-
- if !internal {
- h.len++
- }
- // Add internal handlers to the beginning
- if internal || h.head == nil {
- h.head = &handler{eh, internal, false, h.head}
- return
- }
- // Add handler after internal handlers
- // TODO(austin) This should probably go on the end instead
- prev := h.head
- for prev.next != nil && prev.internal {
- prev = prev.next
- }
- prev.next = &handler{eh, internal, false, prev.next}
-}
-
-func (h *commonHook) RemoveHandler(eh EventHandler) {
- plink := &h.head
- for l := *plink; l != nil; plink, l = &l.next, l.next {
- if l.eh == eh {
- if !l.internal {
- h.len--
- }
- l.removed = true
- *plink = l.next
- break
- }
- }
-}
-
-func (h *commonHook) NumHandler() int { return h.len }
-
-func (h *commonHook) handle(e Event) (EventAction, os.Error) {
- action := EADefault
- plink := &h.head
- for l := *plink; l != nil; plink, l = &l.next, l.next {
- if l.removed {
- continue
- }
- a, err := l.eh(e)
- if a&EARemoveSelf == EARemoveSelf {
- if !l.internal {
- h.len--
- }
- l.removed = true
- *plink = l.next
- a &^= EARemoveSelf
- }
- if err != nil {
- return EAStop, err
- }
- if a > action {
- action = a
- }
- }
- return action, nil
-}
-
-type commonEvent struct {
- // The process of this event
- p *Process
- // The goroutine of this event.
- t *Goroutine
-}
-
-func (e *commonEvent) Process() *Process { return e.p }
-
-func (e *commonEvent) Goroutine() *Goroutine { return e.t }
-
-/*
- * Standard event handlers
- */
-
-// EventPrint is a standard event handler that prints events as they
-// occur. It will not cause the process to stop.
-func EventPrint(ev Event) (EventAction, os.Error) {
- // TODO(austin) Include process name here?
- fmt.Fprintf(os.Stderr, "*** %v\n", ev.String())
- return EADefault, nil
-}
-
-// EventStop is a standard event handler that causes the process to stop.
-func EventStop(ev Event) (EventAction, os.Error) {
- return EAStop, nil
-}
-
-/*
- * Breakpoints
- */
-
-type breakpointHook struct {
- commonHook
- p *Process
- pc proc.Word
-}
-
-// A Breakpoint event occurs when a process reaches a particular
-// program counter. When this event is handled, the current goroutine
-// will be the goroutine that reached the program counter.
-type Breakpoint struct {
- commonEvent
- osThread proc.Thread
- pc proc.Word
-}
-
-func (h *breakpointHook) AddHandler(eh EventHandler) {
- h.addHandler(eh, false)
-}
-
-func (h *breakpointHook) addHandler(eh EventHandler, internal bool) {
- // We register breakpoint events lazily to avoid holding
- // references to breakpoints without handlers. Be sure to use
- // the "canonical" breakpoint if there is one.
- if cur, ok := h.p.breakpointHooks[h.pc]; ok {
- h = cur
- }
- oldhead := h.head
- h.commonHook.addHandler(eh, internal)
- if oldhead == nil && h.head != nil {
- h.p.proc.AddBreakpoint(h.pc)
- h.p.breakpointHooks[h.pc] = h
- }
-}
-
-func (h *breakpointHook) RemoveHandler(eh EventHandler) {
- oldhead := h.head
- h.commonHook.RemoveHandler(eh)
- if oldhead != nil && h.head == nil {
- h.p.proc.RemoveBreakpoint(h.pc)
- h.p.breakpointHooks[h.pc] = nil, false
- }
-}
-
-func (h *breakpointHook) String() string {
- // TODO(austin) Include process name?
- // TODO(austin) Use line:pc or at least sym+%#x
- return fmt.Sprintf("breakpoint at %#x", h.pc)
-}
-
-func (b *Breakpoint) PC() proc.Word { return b.pc }
-
-func (b *Breakpoint) String() string {
- // TODO(austin) Include process name and goroutine
- // TODO(austin) Use line:pc or at least sym+%#x
- return fmt.Sprintf("breakpoint at %#x", b.pc)
-}
-
-/*
- * Goroutine create/exit
- */
-
-type goroutineCreateHook struct {
- commonHook
-}
-
-func (h *goroutineCreateHook) String() string { return "goroutine create" }
-
-// A GoroutineCreate event occurs when a process creates a new
-// goroutine. When this event is handled, the current goroutine will
-// be the newly created goroutine.
-type GoroutineCreate struct {
- commonEvent
- parent *Goroutine
-}
-
-// Parent returns the goroutine that created this goroutine. May be
-// nil if this event is the creation of the first goroutine.
-func (e *GoroutineCreate) Parent() *Goroutine { return e.parent }
-
-func (e *GoroutineCreate) String() string {
- // TODO(austin) Include process name
- if e.parent == nil {
- return fmt.Sprintf("%v created", e.t)
- }
- return fmt.Sprintf("%v created by %v", e.t, e.parent)
-}
-
-type goroutineExitHook struct {
- commonHook
-}
-
-func (h *goroutineExitHook) String() string { return "goroutine exit" }
-
-// A GoroutineExit event occurs when a Go goroutine exits.
-type GoroutineExit struct {
- commonEvent
-}
-
-func (e *GoroutineExit) String() string {
- // TODO(austin) Include process name
- //return fmt.Sprintf("%v exited", e.t);
- // For debugging purposes
- return fmt.Sprintf("goroutine %#x exited", e.t.g.addr().base)
-}