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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [observer.c] - Blame information for rev 841

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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