2 * Copyright 2008-2013, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
6 /*! Provides the networking stack notification service. */
8 #include <net_notifications.h>
10 #include <generic_syscall.h>
11 #include <Notifications.h>
12 #include <util/KMessage.h>
14 //#define TRACE_NOTIFICATIONS
15 #ifdef TRACE_NOTIFICATIONS
16 # define TRACE(x...) dprintf("\33[32mnet_notifications:\33[0m " x)
18 # define TRACE(x...) ;
22 class NetNotificationService
: public DefaultUserNotificationService
{
24 NetNotificationService();
25 virtual ~NetNotificationService();
27 void Notify(const KMessage
& event
);
30 virtual void LastReferenceReleased();
31 virtual void FirstAdded();
32 virtual void LastRemoved();
36 static NetNotificationService sNotificationService
;
39 // #pragma mark - NetNotificationService
42 NetNotificationService::NetNotificationService()
44 DefaultUserNotificationService("network")
49 NetNotificationService::~NetNotificationService()
55 NetNotificationService::Notify(const KMessage
& event
)
57 uint32 opcode
= event
.GetInt32("opcode", 0);
61 TRACE("notify for %lx\n", opcode
);
63 DefaultUserNotificationService::Notify(event
, opcode
);
68 NetNotificationService::LastReferenceReleased()
70 // don't delete us here
75 NetNotificationService::FirstAdded()
77 // The reference counting doesn't work for us, as we'll have to
78 // ensure our module stays loaded.
80 get_module(NET_NOTIFICATIONS_MODULE_NAME
, &dummy
);
85 NetNotificationService::LastRemoved()
87 // Give up the reference _AddListener()
88 put_module(NET_NOTIFICATIONS_MODULE_NAME
);
92 // #pragma mark - User generic syscall
96 net_notifications_control(const char *subsystem
, uint32 function
, void *buffer
,
99 struct net_notifications_control control
;
100 if (bufferSize
!= sizeof(struct net_notifications_control
)
101 || function
!= NET_NOTIFICATIONS_CONTROL_WATCHING
)
103 if (user_memcpy(&control
, buffer
,
104 sizeof(struct net_notifications_control
)) < B_OK
)
105 return B_BAD_ADDRESS
;
107 if (control
.flags
!= 0) {
108 return sNotificationService
.UpdateUserListener(control
.flags
,
109 control
.port
, control
.token
);
112 return sNotificationService
.RemoveUserListeners(control
.port
,
117 // #pragma mark - exported module API
121 send_notification(const KMessage
* event
)
123 sNotificationService
.Notify(*event
);
129 notifications_std_ops(int32 op
, ...)
136 new(&sNotificationService
) NetNotificationService();
137 status_t result
= sNotificationService
.Register();
141 register_generic_syscall(NET_NOTIFICATIONS_SYSCALLS
,
142 net_notifications_control
, 1, 0);
145 case B_MODULE_UNINIT
:
148 unregister_generic_syscall(NET_NOTIFICATIONS_SYSCALLS
, 1);
150 // TODO: due to the way the locking in the notification
151 // manager works, there's a potential race condition here
152 // where someone attempts to add a listener right as
153 // we're uninitializing. Needs to be looked at/resolved.
154 sNotificationService
.Unregister();
156 // we need to release the reference that was acquired
157 // on our behalf by the NotificationManager.
158 sNotificationService
.ReleaseReference();
159 sNotificationService
.~NetNotificationService();
168 net_notifications_module_info sNotificationsModule
= {
170 NET_NOTIFICATIONS_MODULE_NAME
,
172 notifications_std_ops
178 module_info
* modules
[] = {
179 (module_info
*)&sNotificationsModule
,