5 Copyright (C) 2001-2008 Neil Cafferkey
7 This file is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as
9 published by the Free Software Foundation; either version 2.1 of the
10 License, or (at your option) any later version.
12 This file is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with this file; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25 #include "handler_protos.h"
28 static VOID
NotifyObject(struct Handler
*handler
, struct Object
*object
);
32 /****i* ram.handler/MatchNotifyRequests ************************************
35 * MatchNotifyRequests --
38 * MatchNotifyRequests(handler)
40 * VOID MatchNotifyRequests(struct Handler *);
56 ****************************************************************************
60 VOID
MatchNotifyRequests(struct Handler
*handler
)
62 struct Notification
*notification
, *next_notification
, *tail
;
63 struct Object
*object
;
65 next_notification
= (APTR
)handler
->notifications
.mlh_Head
;
66 tail
= (APTR
)&handler
->notifications
.mlh_Tail
;
68 while(next_notification
!= tail
)
70 notification
= next_notification
;
71 next_notification
= (APTR
)((struct MinNode
*)notification
)->mln_Succ
;
73 object
= GetHardObject(handler
, NULL
,
74 notification
->request
->nr_FullName
, NULL
);
77 Remove((APTR
)notification
);
78 AddTail((APTR
)&object
->notifications
, (APTR
)notification
);
87 /****i* ram.handler/UnmatchNotifyRequests **********************************
90 * UnmatchNotifyRequests --
93 * UnmatchNotifyRequests(handler, object)
95 * VOID UnmatchNotifyRequests(struct Handler *, struct Object *);
111 ****************************************************************************
115 VOID
UnmatchNotifyRequests(struct Handler
*handler
, struct Object
*object
)
117 struct Notification
*notification
, *next_notification
, *tail
;
119 next_notification
= (APTR
)object
->notifications
.mlh_Head
;
120 tail
= (APTR
)&object
->notifications
.mlh_Tail
;
122 while(next_notification
!= tail
)
124 notification
= next_notification
;
125 next_notification
= (APTR
)((struct MinNode
*)notification
)->mln_Succ
;
127 Remove((APTR
)notification
);
128 AddTail((APTR
)&handler
->notifications
, (APTR
)notification
);
136 /****i* ram.handler/NotifyAll **********************************************
142 * NotifyAll(handler, object, notify_links)
144 * VOID NotifyAll(struct Handler *, struct Object *, BOOL);
160 ****************************************************************************
164 VOID
NotifyAll(struct Handler
*handler
, struct Object
*object
,
167 struct MinNode
*tail
, *link_node
;
171 object
= GetRealObject(object
);
172 link_node
= object
->hard_link
.mln_Succ
;
173 if(link_node
!= NULL
)
175 tail
= (APTR
)&HARDLINK(link_node
)->elements
.mlh_Tail
;
178 notify_links
= FALSE
;
183 link_node
= &object
->hard_link
;
185 while(link_node
!= tail
)
187 object
= HARDLINK(link_node
);
188 NotifyObject(handler
, object
);
189 NotifyObject(handler
, object
->parent
);
190 link_node
= link_node
->mln_Succ
;
195 NotifyObject(handler
, object
);
196 NotifyObject(handler
, object
->parent
);
204 /****i* ram.handler/NotifyObject *******************************************
210 * NotifyObject(handler, object)
212 * VOID NotifyObject(struct Handler *, struct Object *);
228 ****************************************************************************
232 static VOID
NotifyObject(struct Handler
*handler
, struct Object
*object
)
234 struct Notification
*notification
, *tail
;
238 notification
= (APTR
)object
->notifications
.mlh_Head
;
239 tail
= (APTR
)&object
->notifications
.mlh_Tail
;
241 while(notification
!= tail
)
243 Notify(handler
, notification
);
244 notification
= (APTR
)((struct MinNode
*)notification
)->mln_Succ
;
253 /****i* ram.handler/FindNotification ***************************************
256 * FindNotification --
259 * notification = FindNotification(handler,
262 * struct Notification *FindNotification(struct Handler *,
263 * struct NotifyRequest);
279 ****************************************************************************
283 struct Notification
*FindNotification(struct Handler
*handler
,
284 struct NotifyRequest
*request
)
286 struct Notification
*notification
, *tail
;
287 struct MinList
*list
;
289 struct Object
*object
;
291 /* Find which list the request should be in */
293 object
= GetHardObject(handler
, NULL
, request
->nr_FullName
, NULL
);
295 list
= &object
->notifications
;
297 list
= &handler
->notifications
;
299 /* Search the list */
301 notification
= (APTR
)list
->mlh_Head
;
302 tail
= (APTR
)&list
->mlh_Tail
;
305 while(notification
!= tail
&& !found
)
307 if(notification
->request
== request
)
310 notification
= (APTR
)((struct MinNode
*)notification
)->mln_Succ
;
321 /****i* ram.handler/ReceiveNotifyReply *************************************
324 * ReceiveNotifyReply --
327 * ReceiveNotifyReply(handler, message)
329 * VOID ReceiveNotifyReply(struct Handler *, struct NotifyMessage *);
345 ****************************************************************************
349 VOID
ReceiveNotifyReply(struct Handler
*handler
,
350 struct NotifyMessage
*message
)
352 struct NotifyRequest
*request
;
353 struct Notification
*notification
= NULL
;
355 /* Get request and free message */
357 request
= message
->nm_NReq
;
358 FreePooled(handler
->public_pool
, message
, sizeof(struct NotifyMessage
));
360 /* Get notification if EndNotify() hasn't been called */
362 if(request
->nr_FullName
!= NULL
)
363 notification
= FindNotification(handler
, request
);
364 if(notification
!= NULL
)
366 request
->nr_MsgCount
--;
368 /* Send a new notification if there's one pending */
370 if((request
->nr_Flags
& NRF_MAGIC
) != 0)
372 request
->nr_Flags
&= ~NRF_MAGIC
;
373 Notify(handler
, notification
);
382 /****i* ram.handler/Notify *************************************************
388 * Notify(handler, notification)
390 * VOID Notify(struct Handler *, struct Notification *);
406 ****************************************************************************
410 VOID
Notify(struct Handler
*handler
, struct Notification
*notification
)
412 struct NotifyMessage
*message
;
413 struct NotifyRequest
*request
;
416 request
= notification
->request
;
417 flags
= request
->nr_Flags
;
418 if((flags
& NRF_SEND_MESSAGE
) != 0)
420 /* Send message now or remember to send it later */
422 if((flags
& NRF_WAIT_REPLY
) == 0 || request
->nr_MsgCount
== 0)
424 message
= AllocPooled(handler
->public_pool
,
425 sizeof(struct NotifyMessage
));
428 ((struct Message
*)message
)->mn_ReplyPort
=
429 handler
->notify_port
;
430 ((struct Message
*)message
)->mn_Length
=
431 sizeof(struct NotifyMessage
);
432 message
->nm_NReq
= request
;
433 message
->nm_Class
= NOTIFY_CLASS
;
434 message
->nm_Code
= NOTIFY_CODE
;
436 PutMsg(request
->nr_stuff
.nr_Msg
.nr_Port
, (APTR
)message
);
437 request
->nr_MsgCount
++;
441 request
->nr_Flags
|= NRF_MAGIC
;
445 Signal(request
->nr_stuff
.nr_Signal
.nr_Task
,
446 1 << (request
->nr_stuff
.nr_Signal
.nr_SignalNum
));