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

Subversion Repositories openrisc_me

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

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

Line No. Rev Author Line
1 227 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
  node->observer = XMALLOC (struct observer);
95
  return node;
96
}
97
 
98
/* The opposite of xalloc_observer_list_node, frees the memory for
99
   the given node.  */
100
 
101
static void
102
xfree_observer_list_node (struct observer_list *node)
103
{
104
  xfree (node->observer);
105
  xfree (node);
106
}
107
 
108
/* Attach the callback NOTIFY to a SUBJECT.  The DATA is also stored,
109
   in order for the subject to provide it back to the observer during
110
   a notification.  */
111
 
112
static struct observer *
113
generic_observer_attach (struct observer_list **subject,
114
                         generic_observer_notification_ftype * notify,
115
                         void *data)
116
{
117
  struct observer_list *observer_list = xalloc_observer_list_node ();
118
 
119
  observer_list->next = *subject;
120
  observer_list->observer->notify = notify;
121
  observer_list->observer->data = data;
122
  *subject = observer_list;
123
 
124
  return observer_list->observer;
125
}
126
 
127
/* Remove the given OBSERVER from the SUBJECT.  Once detached, OBSERVER
128
   should no longer be used, as it is no longer valid.  */
129
 
130
static void
131
generic_observer_detach (struct observer_list **subject,
132
                         const struct observer *observer)
133
{
134
  struct observer_list *previous_node = NULL;
135
  struct observer_list *current_node = *subject;
136
 
137
  while (current_node != NULL)
138
    {
139
      if (current_node->observer == observer)
140
        {
141
          if (previous_node != NULL)
142
            previous_node->next = current_node->next;
143
          else
144
            *subject = current_node->next;
145
          xfree_observer_list_node (current_node);
146
          return;
147
        }
148
      previous_node = current_node;
149
      current_node = current_node->next;
150
    }
151
 
152
  /* We should never reach this point.  However, this should not be
153
     a very serious error, so simply report a warning to the user.  */
154
  warning (_("Failed to detach observer"));
155
}
156
 
157
/* Send a notification to all the observers of SUBJECT.  ARGS is passed to
158
   all observers as an argument to the notification callback.  */
159
 
160
static void
161
generic_observer_notify (struct observer_list *subject, const void *args)
162
{
163
  struct observer_list *current_node = subject;
164
 
165
  while (current_node != NULL)
166
    {
167
      (*current_node->observer->notify) (current_node->observer->data, args);
168
      current_node = current_node->next;
169
    }
170
}
171
 
172
 
173
/* The following code is only used to unit-test the observers from our
174
   testsuite.  DO NOT USE IT within observer.c (or anywhere else for
175
   that matter)!  */
176
 
177
/* If we define these variables and functions as `static', the
178
   compiler will optimize them out.  */
179
 
180
int observer_test_first_observer = 0;
181
int observer_test_second_observer = 0;
182
int observer_test_third_observer = 0;
183
 
184
void
185
observer_test_first_notification_function (int arg)
186
{
187
  observer_test_first_observer++;
188
}
189
 
190
void
191
observer_test_second_notification_function (int arg)
192
{
193
  observer_test_second_observer++;
194
}
195
 
196
void
197
observer_test_third_notification_function (int arg)
198
{
199
  observer_test_third_observer++;
200
}
201
 
202
extern initialize_file_ftype _initialize_observer; /* -Wmissing-prototypes */
203
 
204
void
205
_initialize_observer (void)
206
{
207
  add_setshow_zinteger_cmd ("observer", class_maintenance,
208
                            &observer_debug, _("\
209
Set observer debugging."), _("\
210
Show observer debugging."), _("\
211
When non-zero, observer debugging is enabled."),
212
                            NULL,
213
                            show_observer_debug,
214
                            &setdebuglist, &showdebuglist);
215
}
216
 
217
#include "observer.inc"

powered by: WebSVN 2.1.0

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