2005-03-25 Dan Williams <dcbw@redhat.com>
* panel-applet/NMWirelessApplet.c - (nmwa_about_cb): Add some more contributors - (nmwa_update_state): show the applet when there's no connection - Enable the "Stop/Resume all wireless devices" option in the context menu - New "no connection" icon * src/NetworkManager.c - (nm_poll_and_update_wireless_link_state): don't do anything if wireless is disabled or we're asleep * src/NetworkManagerDHCP.c - Remove trailing "\n" on debug messages * src/NetworkManagerDbus.c - (nm_dbus_network_status_from_data): new state "asleep" * src/NetworkManagerDevice.c - Merge most of Peter Jones' "completion" patch that greatly reduces latency and wait times for most operations - (nm_device_wireless_scan): Don't scan when asleep * src/NetworkManagerPolicy.c - (nm_policy_get_best_device): return no device when asleep - (nm_policy_allowed_ap_list_update): From Bill Moss: merge properties for all wireless devices on update, not just active device * src/NetworkManagerUtils.c - Merge Peter Jones' "completion" patch * src/nm-dbus-nm.c - (nm_dbus_nm_set_wireless_enabled): bring down wireless devices when we're told to disable them - (nm_dbus_nm_sleep, nm_dbus_nm_wake): new functions for sleep/wake * utils/nm-utils.h - New variants of the warn/info/error/debug print functions that can take variables rather than static strings git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@510 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
@@ -25,6 +25,9 @@
|
||||
#include <sys/socket.h>
|
||||
#include <linux/sockios.h>
|
||||
#include <syslog.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/time.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "NetworkManager.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
@@ -426,3 +429,223 @@ NMDriverSupportLevel nm_get_driver_support_level (LibHalContext *ctx, NMDevice *
|
||||
g_free (driver);
|
||||
return (level);
|
||||
}
|
||||
|
||||
static inline int nm_timeval_cmp(const struct timeval *a,
|
||||
const struct timeval *b)
|
||||
{
|
||||
int x;
|
||||
x = a->tv_sec - b->tv_sec;
|
||||
x *= G_USEC_PER_SEC;
|
||||
if (x)
|
||||
return x;
|
||||
x = a->tv_usec - b->tv_usec;
|
||||
if (x)
|
||||
return x;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int nm_timeval_has_passed(const struct timeval *a)
|
||||
{
|
||||
struct timeval current;
|
||||
|
||||
gettimeofday(¤t, NULL);
|
||||
|
||||
return (nm_timeval_cmp(¤t, a) >= 0);
|
||||
}
|
||||
|
||||
static inline void nm_timeval_add(struct timeval *a,
|
||||
const struct timeval *b)
|
||||
{
|
||||
struct timeval b1;
|
||||
|
||||
memmove(&b1, b, sizeof b1);
|
||||
|
||||
/* normalize a and b to be positive for everything */
|
||||
while (a->tv_usec < 0)
|
||||
{
|
||||
a->tv_sec--;
|
||||
a->tv_usec += G_USEC_PER_SEC;
|
||||
}
|
||||
while (b1.tv_usec < 0)
|
||||
{
|
||||
b1.tv_sec--;
|
||||
b1.tv_usec += G_USEC_PER_SEC;
|
||||
}
|
||||
|
||||
/* now add secs and usecs */
|
||||
a->tv_sec += b1.tv_sec;
|
||||
a->tv_usec += b1.tv_usec;
|
||||
|
||||
/* and handle our overflow */
|
||||
if (a->tv_usec > G_USEC_PER_SEC)
|
||||
{
|
||||
a->tv_sec++;
|
||||
a->tv_usec -= G_USEC_PER_SEC;
|
||||
}
|
||||
}
|
||||
|
||||
static void nm_v_wait_for_completion_or_timeout(
|
||||
const int max_tries,
|
||||
const struct timeval *max_time,
|
||||
const guint interval_usecs,
|
||||
nm_completion_func test_func,
|
||||
nm_completion_func action_func,
|
||||
va_list args)
|
||||
{
|
||||
int try;
|
||||
gboolean finished = FALSE;
|
||||
struct timeval finish_time;
|
||||
|
||||
g_return_if_fail (test_func || action_func);
|
||||
|
||||
if (max_time) {
|
||||
gettimeofday(&finish_time, NULL);
|
||||
nm_timeval_add(&finish_time, max_time);
|
||||
}
|
||||
|
||||
try = -1;
|
||||
while (!finished &&
|
||||
(max_tries == NM_COMPLETION_TRIES_INFINITY || try < max_tries))
|
||||
{
|
||||
if (max_time && nm_timeval_has_passed(&finish_time))
|
||||
break;
|
||||
try++;
|
||||
if (test_func)
|
||||
{
|
||||
finished = (*test_func)(try, args);
|
||||
if (finished)
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#define NM_SLEEP_DEBUG
|
||||
#endif
|
||||
#ifdef NM_SLEEP_DEBUG
|
||||
syslog (LOG_INFO, "sleeping or %d usecs", interval_usecs);
|
||||
#endif
|
||||
g_usleep(interval_usecs);
|
||||
if (action_func)
|
||||
finished = (*action_func)(try, args);
|
||||
}
|
||||
}
|
||||
|
||||
void nm_wait_for_completion_or_timeout(
|
||||
const int max_tries,
|
||||
const struct timeval *max_time,
|
||||
const guint interval_usecs,
|
||||
nm_completion_func test_func,
|
||||
nm_completion_func action_func,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, action_func);
|
||||
|
||||
nm_v_wait_for_completion_or_timeout(max_tries, max_time,
|
||||
interval_usecs, test_func,
|
||||
action_func, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void nm_wait_for_completion(
|
||||
const int max_tries,
|
||||
const guint interval_usecs,
|
||||
nm_completion_func test_func,
|
||||
nm_completion_func action_func,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, action_func);
|
||||
|
||||
nm_v_wait_for_completion_or_timeout(max_tries, NULL,
|
||||
interval_usecs, test_func,
|
||||
action_func, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void nm_wait_for_timeout(
|
||||
const struct timeval *max_time,
|
||||
const guint interval_usecs,
|
||||
nm_completion_func test_func,
|
||||
nm_completion_func action_func,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, action_func);
|
||||
|
||||
nm_v_wait_for_completion_or_timeout(-1, max_time,
|
||||
interval_usecs, test_func,
|
||||
action_func, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/* you can use these, but they're really just examples */
|
||||
gboolean nm_completion_boolean_test(int tries, va_list args)
|
||||
{
|
||||
gboolean *condition = va_arg(args, gboolean *);
|
||||
char *message = va_arg(args, char *);
|
||||
int log_level = va_arg(args, int);
|
||||
int log_interval = va_arg(args, int);
|
||||
|
||||
g_return_val_if_fail (condition != NULL, TRUE);
|
||||
|
||||
if (message)
|
||||
if ((log_interval == 0 && tries == 0) || (log_interval != 0 && tries % log_interval == 0))
|
||||
{
|
||||
if (log_level == LOG_WARNING)
|
||||
nm_warning_str (message);
|
||||
else if (log_level == LOG_ERR)
|
||||
nm_error_str (message);
|
||||
else if (log_level == LOG_DEBUG)
|
||||
nm_debug_str (message);
|
||||
else
|
||||
nm_info_str (message);
|
||||
}
|
||||
|
||||
if (*condition)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean nm_completion_boolean_function1_test(int tries, va_list args)
|
||||
{
|
||||
nm_completion_boolean_function_1 condition =
|
||||
va_arg(args, nm_completion_boolean_function_1);
|
||||
char *message = va_arg(args, char *);
|
||||
int log_level = va_arg(args, int);
|
||||
int log_interval = va_arg(args, int);
|
||||
u_int64_t arg0 = va_arg(args, unsigned long long);
|
||||
|
||||
g_return_val_if_fail (condition, TRUE);
|
||||
|
||||
if (message)
|
||||
if ((log_interval == 0 && tries == 0)
|
||||
|| (log_interval != 0 && tries % log_interval == 0))
|
||||
syslog(log_level, message);
|
||||
|
||||
if (!(*condition)(arg0))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean nm_completion_boolean_function2_test(int tries, va_list args)
|
||||
{
|
||||
nm_completion_boolean_function_2 condition =
|
||||
va_arg(args, nm_completion_boolean_function_2);
|
||||
char *message = va_arg(args, char *);
|
||||
int log_level = va_arg(args, int);
|
||||
int log_interval = va_arg(args, int);
|
||||
u_int64_t arg0 = va_arg(args, unsigned long long);
|
||||
u_int64_t arg1 = va_arg(args, unsigned long long);
|
||||
|
||||
g_return_val_if_fail (condition, TRUE);
|
||||
|
||||
if (message)
|
||||
if ((log_interval == 0 && tries == 0)
|
||||
|| (log_interval != 0 && tries % log_interval == 0))
|
||||
syslog(log_level, message);
|
||||
|
||||
if (!(*condition)(arg0, arg1))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user