* Removed the polling of the network status; instead, it now uses the new

network notifications.
* It also doesn't keep a socket open over the whole time which would prevent
  the network stack to be unloaded.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29904 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-04-04 17:12:18 +00:00
parent 8dd71c2b23
commit 195981bb59
3 changed files with 75 additions and 48 deletions
+1 -1
View File
@@ -2,7 +2,7 @@ SubDir HAIKU_TOP src apps networkstatus ;
SetSubDirSupportedPlatformsBeOSCompatible ; SetSubDirSupportedPlatformsBeOSCompatible ;
UsePrivateHeaders shared ; UsePrivateHeaders net shared ;
UseLibraryHeaders agg icon ; UseLibraryHeaders agg icon ;
local icon_libs ; local icon_libs ;
+73 -44
View File
@@ -11,8 +11,14 @@
#include "NetworkStatusView.h" #include "NetworkStatusView.h"
#include "NetworkStatus.h" #include <arpa/inet.h>
#include "NetworkStatusIcons.h" #include <net/if.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <unistd.h>
#include <Alert.h> #include <Alert.h>
#include <Application.h> #include <Application.h>
@@ -29,22 +35,11 @@
#include <String.h> #include <String.h>
#include <TextView.h> #include <TextView.h>
#include <arpa/inet.h> #include <net_notifications.h>
#include <net/if.h>
#include <stdio.h> #include "NetworkStatus.h"
#include <stdlib.h> #include "NetworkStatusIcons.h"
#include <string.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <unistd.h>
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
// BONE compatibility
# define IF_NAMESIZE IFNAMSIZ
# define IFF_LINK 0
# define IFF_CONFIGURING 0
# define ifc_value ifc_val
#endif
static const char *kStatusDescriptions[] = { static const char *kStatusDescriptions[] = {
"Unknown", "Unknown",
@@ -57,15 +52,41 @@ static const char *kStatusDescriptions[] = {
extern "C" _EXPORT BView *instantiate_deskbar_item(void); extern "C" _EXPORT BView *instantiate_deskbar_item(void);
const uint32 kMsgUpdate = 'updt';
const uint32 kMsgShowConfiguration = 'shcf'; const uint32 kMsgShowConfiguration = 'shcf';
const uint32 kMsgOpenNetworkPreferences = 'onwp'; const uint32 kMsgOpenNetworkPreferences = 'onwp';
const uint32 kMinIconWidth = 16; const uint32 kMinIconWidth = 16;
const uint32 kMinIconHeight = 16; const uint32 kMinIconHeight = 16;
const bigtime_t kUpdateInterval = 1000000;
// every second class SocketOpener {
public:
SocketOpener()
{
fSocket = socket(AF_INET, SOCK_DGRAM, 0);
}
~SocketOpener()
{
close(fSocket);
}
status_t InitCheck()
{
return fSocket >= 0 ? B_OK : B_ERROR;
}
operator int() const
{
return fSocket;
}
private:
int fSocket;
};
// #pragma mark -
NetworkStatusView::NetworkStatusView(BRect frame, int32 resizingMode, NetworkStatusView::NetworkStatusView(BRect frame, int32 resizingMode,
@@ -111,8 +132,6 @@ NetworkStatusView::~NetworkStatusView()
void void
NetworkStatusView::_Init() NetworkStatusView::_Init()
{ {
fMessageRunner = NULL;
for (int i = 0; i < kStatusCount; i++) { for (int i = 0; i < kStatusCount; i++) {
fBitmaps[i] = NULL; fBitmaps[i] = NULL;
} }
@@ -206,10 +225,9 @@ NetworkStatusView::AttachedToWindow()
SetLowColor(ViewColor()); SetLowColor(ViewColor());
BMessage update(kMsgUpdate); start_watching_network(
fMessageRunner = new BMessageRunner(this, &update, kUpdateInterval); B_WATCH_NETWORK_INTERFACE_CHANGES | B_WATCH_NETWORK_LINK_CHANGES, this);
fSocket = socket(AF_INET, SOCK_DGRAM, 0);
_Update(); _Update();
} }
@@ -217,8 +235,7 @@ NetworkStatusView::AttachedToWindow()
void void
NetworkStatusView::DetachedFromWindow() NetworkStatusView::DetachedFromWindow()
{ {
delete fMessageRunner; stop_watching_network(this);
close(fSocket);
} }
@@ -226,7 +243,7 @@ void
NetworkStatusView::MessageReceived(BMessage* message) NetworkStatusView::MessageReceived(BMessage* message)
{ {
switch (message->what) { switch (message->what) {
case kMsgUpdate: case B_NETWORK_MONITOR:
_Update(); _Update();
break; break;
@@ -276,8 +293,8 @@ void
NetworkStatusView::_ShowConfiguration(BMessage* message) NetworkStatusView::_ShowConfiguration(BMessage* message)
{ {
static const struct information_entry { static const struct information_entry {
const char *label; const char* label;
int32 control; int32 control;
} kInformationEntries[] = { } kInformationEntries[] = {
{ "Address", SIOCGIFADDR }, { "Address", SIOCGIFADDR },
{ "Broadcast", SIOCGIFBRDADDR }, { "Broadcast", SIOCGIFBRDADDR },
@@ -285,7 +302,11 @@ NetworkStatusView::_ShowConfiguration(BMessage* message)
{ NULL } { NULL }
}; };
const char *name; SocketOpener socket;
if (socket.InitCheck() != B_OK)
return;
const char* name;
if (message->FindString("interface", &name) != B_OK) if (message->FindString("interface", &name) != B_OK)
return; return;
@@ -298,7 +319,7 @@ NetworkStatusView::_ShowConfiguration(BMessage* message)
size_t boldLength = text.Length(); size_t boldLength = text.Length();
for (int i = 0; kInformationEntries[i].label; i++) { for (int i = 0; kInformationEntries[i].label; i++) {
if (ioctl(fSocket, kInformationEntries[i].control, &request, if (ioctl(socket, kInformationEntries[i].control, &request,
sizeof(request)) < 0) { sizeof(request)) < 0) {
continue; continue;
} }
@@ -341,7 +362,7 @@ NetworkStatusView::_ShowConfiguration(BMessage* message)
void void
NetworkStatusView::MouseDown(BPoint point) NetworkStatusView::MouseDown(BPoint point)
{ {
BPopUpMenu *menu = new BPopUpMenu(B_EMPTY_STRING, false, false); BPopUpMenu* menu = new BPopUpMenu(B_EMPTY_STRING, false, false);
menu->SetAsyncAutoDestruct(true); menu->SetAsyncAutoDestruct(true);
menu->SetFont(be_plain_font); menu->SetFont(be_plain_font);
@@ -376,7 +397,7 @@ NetworkStatusView::MouseDown(BPoint point)
void void
NetworkStatusView::_AboutRequested() NetworkStatusView::_AboutRequested()
{ {
BAlert *alert = new BAlert("about", "NetworkStatus\n" BAlert* alert = new BAlert("about", "NetworkStatus\n"
"\twritten by Axel Dörfler and Hugo Santos\n" "\twritten by Axel Dörfler and Hugo Santos\n"
"\tCopyright 2007, Haiku, Inc.\n", "Ok"); "\tCopyright 2007, Haiku, Inc.\n", "Ok");
BTextView *view = alert->TextView(); BTextView *view = alert->TextView();
@@ -407,12 +428,16 @@ NetworkStatusView::_PrepareRequest(struct ifreq& request, const char* name)
int32 int32
NetworkStatusView::_DetermineInterfaceStatus(const char* name) NetworkStatusView::_DetermineInterfaceStatus(const char* name)
{ {
SocketOpener socket;
if (socket.InitCheck() != B_OK)
return kStatusUnknown;
ifreq request; ifreq request;
if (!_PrepareRequest(request, name)) if (!_PrepareRequest(request, name))
return kStatusUnknown; return kStatusUnknown;
uint32 flags = 0; uint32 flags = 0;
if (ioctl(fSocket, SIOCGIFFLAGS, &request, sizeof(struct ifreq)) == 0) if (ioctl(socket, SIOCGIFFLAGS, &request, sizeof(struct ifreq)) == 0)
flags = request.ifr_flags; flags = request.ifr_flags;
int32 status = kStatusNoLink; int32 status = kStatusNoLink;
@@ -431,29 +456,33 @@ NetworkStatusView::_DetermineInterfaceStatus(const char* name)
void void
NetworkStatusView::_Update(bool force) NetworkStatusView::_Update(bool force)
{ {
SocketOpener socket;
if (socket.InitCheck() != B_OK)
return;
// iterate over all interfaces and retrieve minimal status // iterate over all interfaces and retrieve minimal status
ifconf config; ifconf config;
config.ifc_len = sizeof(config.ifc_value); config.ifc_len = sizeof(config.ifc_value);
if (ioctl(fSocket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0) if (ioctl(socket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0)
return; return;
uint32 count = (uint32)config.ifc_value; uint32 count = (uint32)config.ifc_value;
if (count == 0) if (count == 0)
return; return;
void *buffer = malloc(count * sizeof(struct ifreq)); void* buffer = malloc(count * sizeof(struct ifreq));
if (buffer == NULL) if (buffer == NULL)
return; return;
config.ifc_len = count * sizeof(struct ifreq); config.ifc_len = count * sizeof(struct ifreq);
config.ifc_buf = buffer; config.ifc_buf = buffer;
if (ioctl(fSocket, SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0) { if (ioctl(socket, SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0) {
free(buffer); free(buffer);
return; return;
} }
ifreq *interface = (ifreq *)buffer; ifreq* interface = (ifreq*)buffer;
int32 oldStatus = fStatus; int32 oldStatus = fStatus;
fStatus = kStatusUnknown; fStatus = kStatusUnknown;
@@ -481,15 +510,15 @@ NetworkStatusView::_Update(bool force)
void void
NetworkStatusView::_OpenNetworksPreferences() NetworkStatusView::_OpenNetworksPreferences()
{ {
status_t ret = be_roster->Launch("application/x-vnd.Haiku-Network"); status_t status = be_roster->Launch("application/x-vnd.Haiku-Network");
if (ret < B_OK) { if (status < B_OK) {
BString errorMessage("Launching the Network preflet failed.\n\n" BString errorMessage("Launching the Network preflet failed.\n\n"
"Error: "); "Error: ");
errorMessage << strerror(ret); errorMessage << strerror(status);
BAlert* alert = new BAlert("launch error", errorMessage.String(), BAlert* alert = new BAlert("launch error", errorMessage.String(),
"Ok"); "Ok");
// asynchronous alert in order to not block replicant host
// application // asynchronous alert in order to not block replicant host application
alert->Go(NULL); alert->Go(NULL);
} }
} }
+1 -3
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006-2007, Haiku, Inc. All Rights Reserved. * Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -56,12 +56,10 @@ class NetworkStatusView : public BView {
void _Update(bool force = false); void _Update(bool force = false);
void _OpenNetworksPreferences(); void _OpenNetworksPreferences();
BMessageRunner* fMessageRunner;
BObjectList<BString> fInterfaces; BObjectList<BString> fInterfaces;
bool fInDeskbar; bool fInDeskbar;
BBitmap* fBitmaps[kStatusCount]; BBitmap* fBitmaps[kStatusCount];
int32 fStatus; int32 fStatus;
int fSocket;
}; };
#endif // NETWORK_STATUS_VIEW_H #endif // NETWORK_STATUS_VIEW_H