OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [gdb/] [observer.c] - Blame information for rev 294

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/* GDB Notifications to Observers.
2
 
3
   Copyright (C) 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
4
 
5
   This file is part of GDB.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
 
20
/* An observer is an entity who is interested in being notified when GDB
21
   reaches certain states, or certain events occur in GDB. The entity being
22
   observed is called the Subject. To receive notifications, the observer
23
   attaches a callback to the subject. One subject can have several
24
   observers.
25
 
26
   This file implements an internal generic low-level event notification
27
   mechanism based on the Observer paradigm described in the book "Design
28
   Patterns".  This generic event notification mechansim is then re-used
29
   to implement the exported high-level notification management routines
30
   for all possible notifications.
31
 
32
   The current implementation of the generic observer provides support
33
   for contextual data. This contextual data is given to the subject
34
   when attaching the callback. In return, the subject will provide
35
   this contextual data back to the observer as a parameter of the
36
   callback.
37
 
38
   FIXME: The current support for the contextual data is only partial,
39
   as it lacks a mechanism that would deallocate this data when the
40
   callback is detached. This is not a problem so far, as this contextual
41
   data is only used internally to hold a function pointer. Later on,
42
   if a certain observer needs to provide support for user-level
43
   contextual data, then the generic notification mechanism will need
44
   need to be enhanced to allow the observer to provide a routine to
45
   deallocate the data when attaching the callback.
46
 
47
   This file is currently maintained by hand, but the long term plan
48
   if the number of different notifications starts growing is to create
49
   a new script (observer.sh) that would generate this file, and the
50
   associated documentation.  */
51
 
52
#include "defs.h"
53
#include "observer.h"
54
#include "command.h"
55
#include "gdbcmd.h"
56
 
57
static int observer_debug;
58
static void
59
show_observer_debug (struct ui_file *file, int from_tty,
60
                     struct cmd_list_element *c, const char *value)
61
{
62
  fprintf_filtered (file, _("Observer debugging is %s.\n"), value);
63
}
64
 
65
/* The internal generic observer.  */
66
 
67
typedef void (generic_observer_notification_ftype) (const void *data,
68
                                                    const void *args);
69
 
70
struct observer
71
{
72
  generic_observer_notification_ftype *notify;
73
  /* No memory management needed for the following field for now.  */
74
  void *data;
75
};
76
 
77
/* A list of observers, maintained by the subject.  A subject is
78
   actually represented by its list of observers.  */
79
 
80
struct observer_list
81
{
82
  struct observer_list *next;
83
  struct observer *observer;
84
};
85
 
86
/* Allocate a struct observer_list, intended to be used as a node
87
   in the list of observers maintained by a subject.  */
88
 
89
static struct observer_list *
90
xalloc_observer_list_node (void)
91
{
92
  struct observer_list *node = XMALLOC (struct observer_list);
93
  node->observer = XMALLOC (struct observer);
94
  return node;
95
}
96
 
97
/* The opposite of xalloc_observer_list_node, frees the memory for
98
   the given node.  */
99
 
100
static void
101
xfree_observer_list_node (struct observer_list *node)
102
{
103
  xfree (node->observer);
104
  xfree (node);
105
}
106
 
107
/* Attach the callback NOTIFY to a SUBJECT.  The DATA is also stored,
108
   in order for the subject to provide it back to the observer during
109
   a notification.  */
110
 
111
static struct observer *
112
generic_observer_attach (struct observer_list **subject,
113
                         generic_observer_notification_ftype * notify,
114
                         void *data)
115
{
116
  struct observer_list *observer_list = xalloc_observer_list_node ();
117
 
118
  observer_list->next = *subject;
119
  observer_list->observer->notify = notify;
120
  observer_list->observer->data = data;
121
  *subject = observer_list;
122
 
123
  return observer_list->observer;
124
}
125
 
126
/* Remove the given OBSERVER from the SUBJECT.  Once detached, OBSERVER
127
   should no longer be used, as it is no longer valid.  */
128
 
129
static void
130
generic_observer_detach (struct observer_list **subject,
131
                         const struct observer *observer)
132
{
133
  struct observer_list *previous_node = NULL;
134
  struct observer_list *current_node = *subject;
135
 
136
  while (current_node != NULL)
137
    {
138
      if (current_node->observer == observer)
139
        {
140
          if (previous_node != NULL)
141
            previous_node->next = current_node->next;
142
          else
143
            *subject = current_node->next;
144
          xfree_observer_list_node (current_node);
145
          return;
146
        }
147
      previous_node = current_node;
148
      current_node = current_node->next;
149
    }
150
 
151
  /* We should never reach this point.  However, this should not be
152
     a very serious error, so simply report a warning to the user.  */
153
  warning (_("Failed to detach observer"));
154
}
155
 
156
/* Send a notification to all the observers of SUBJECT.  ARGS is passed to
157
   all observers as an argument to the notification callback.  */
158
 
159
static void
160
generic_observer_notify (struct observer_list *subject, const void *args)
161
{
162
  struct observer_list *current_node = subject;
163
 
164
  while (current_node != NULL)
165
    {
166
      (*current_node->observer->notify) (current_node->observer->data, args);
167
      current_node = current_node->next;
168
    }
169
}
170
 
171
 
172
/* The following code is only used to unit-test the observers from our
173
   testsuite.  DO NOT USE IT within observer.c (or anywhere else for
174
   that matter)!  */
175
 
176
/* If we define these variables and functions as `static', the
177
   compiler will optimize them out.  */
178
 
179
int observer_test_first_observer = 0;
180
int observer_test_second_observer = 0;
181
int observer_test_third_observer = 0;
182
 
183
void
184
observer_test_first_notification_function (struct bpstats *bs)
185
{
186
  observer_test_first_observer++;
187
}
188
 
189
void
190
observer_test_second_notification_function (struct bpstats *bs)
191
{
192
  observer_test_second_observer++;
193
}
194
 
195
void
196
observer_test_third_notification_function (struct bpstats *bs)
197
{
198
  observer_test_third_observer++;
199
}
200
 
201
extern initialize_file_ftype _initialize_observer; /* -Wmissing-prototypes */
202
 
203
void
204
_initialize_observer (void)
205
{
206
  add_setshow_zinteger_cmd ("observer", class_maintenance,
207
                            &observer_debug, _("\
208
Set observer debugging."), _("\
209
Show observer debugging."), _("\
210
When non-zero, observer debugging is enabled."),
211
                            NULL,
212
                            show_observer_debug,
213
                            &setdebuglist, &showdebuglist);
214
}
215
 
216
#include "observer.inc"

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.