BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / kernel / network / notifications / notifications.cpp
blob839edab2358a2df36b009835285979fb87daa903
1 /*
2 * Copyright 2008-2013, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
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)
17 #else
18 # define TRACE(x...) ;
19 #endif
22 class NetNotificationService : public DefaultUserNotificationService {
23 public:
24 NetNotificationService();
25 virtual ~NetNotificationService();
27 void Notify(const KMessage& event);
29 protected:
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()
54 void
55 NetNotificationService::Notify(const KMessage& event)
57 uint32 opcode = event.GetInt32("opcode", 0);
58 if (opcode == 0)
59 return;
61 TRACE("notify for %lx\n", opcode);
63 DefaultUserNotificationService::Notify(event, opcode);
67 void
68 NetNotificationService::LastReferenceReleased()
70 // don't delete us here
74 void
75 NetNotificationService::FirstAdded()
77 // The reference counting doesn't work for us, as we'll have to
78 // ensure our module stays loaded.
79 module_info* dummy;
80 get_module(NET_NOTIFICATIONS_MODULE_NAME, &dummy);
84 void
85 NetNotificationService::LastRemoved()
87 // Give up the reference _AddListener()
88 put_module(NET_NOTIFICATIONS_MODULE_NAME);
92 // #pragma mark - User generic syscall
95 static status_t
96 net_notifications_control(const char *subsystem, uint32 function, void *buffer,
97 size_t bufferSize)
99 struct net_notifications_control control;
100 if (bufferSize != sizeof(struct net_notifications_control)
101 || function != NET_NOTIFICATIONS_CONTROL_WATCHING)
102 return B_BAD_VALUE;
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,
113 control.token);
117 // #pragma mark - exported module API
120 static status_t
121 send_notification(const KMessage* event)
123 sNotificationService.Notify(*event);
124 return B_OK;
128 static status_t
129 notifications_std_ops(int32 op, ...)
131 switch (op) {
132 case B_MODULE_INIT:
134 TRACE("init\n");
136 new(&sNotificationService) NetNotificationService();
137 status_t result = sNotificationService.Register();
138 if (result != B_OK)
139 return result;
141 register_generic_syscall(NET_NOTIFICATIONS_SYSCALLS,
142 net_notifications_control, 1, 0);
143 return B_OK;
145 case B_MODULE_UNINIT:
146 TRACE("uninit\n");
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();
160 return B_OK;
162 default:
163 return B_ERROR;
168 net_notifications_module_info sNotificationsModule = {
170 NET_NOTIFICATIONS_MODULE_NAME,
172 notifications_std_ops
175 send_notification
178 module_info* modules[] = {
179 (module_info*)&sNotificationsModule,
180 NULL