Ping clients regularly to make the "unresponsive" message more responsive. Please notify me of any performance problems caused by this change.

This commit is contained in:
Kris Maglione 2010-06-02 02:09:23 -04:00
parent fb1d7443a1
commit 625246858d
9 changed files with 64 additions and 57 deletions

View File

@ -624,7 +624,7 @@ client_configure(Client *c) {
void
client_message(Client *c, char *msg, long l2) {
sendmessage(&c->w, "WM_PROTOCOLS", xatom(msg), xtime, l2, 0, 0);
sendmessage(&c->w, "WM_PROTOCOLS", xatom(msg), event_xtime, l2, 0, 0);
}
void
@ -633,6 +633,7 @@ client_kill(Client *c, bool nice) {
ulong *pid;
long n;
c->dead = 1;
if(!nice) {
getprop_textlist(&c->w, "WM_CLIENT_MACHINE", &host);
n = getprop_ulong(&c->w, Net("WM_PID"), "CARDINAL", 0, &pid, 1);
@ -643,10 +644,8 @@ client_kill(Client *c, bool nice) {
XKillClient(display, c->w.xid);
}
else if(c->proto & ProtoDelete) {
else if(c->proto & ProtoDelete)
client_message(c, "WM_DELETE_WINDOW", 0);
ewmh_pingclient(c);
}
else
XKillClient(display, c->w.xid);
}

View File

@ -25,6 +25,8 @@
enum {
PingTime = 10000,
PingPeriod = 2000,
PingPartition = 20,
};
enum IncMode {
@ -166,6 +168,7 @@ struct Client {
char props[512];
long proto;
uint border;
int dead;
int fullscreen;
bool floating;
bool fixedsize;
@ -345,7 +348,6 @@ EXTERN long ignoreenter;
EXTERN bool resizing;
EXTERN int starting;
EXTERN char* user;
EXTERN long xtime;
EXTERN Client* kludge;

View File

@ -9,6 +9,7 @@ Window *ewmhwin;
static void ewmh_getwinstate(Client*);
static void ewmh_setstate(Client*, Atom, int);
static void tick(long, void*);
static Handlers client_handlers;
static Handlers root_handlers;
@ -27,12 +28,13 @@ ewmh_init(void) {
changeprop_long(ewmhwin, Net("SUPPORTING_WM_CHECK"), "WINDOW", &win, 1);
changeprop_string(ewmhwin, Net("WM_NAME"), myname);
long zz[] = {0, 0};
changeprop_long(&scr.root, Net("DESKTOP_VIEWPORT"), "CARDINAL",
zz, 2);
(long[2]){0, 0}, 2);
pushhandler(&scr.root, &root_handlers, nil);
tick(0L, nil);
long supported[] = {
/* Misc */
NET("SUPPORTED"),
@ -45,6 +47,7 @@ ewmh_init(void) {
NET("WM_DESKTOP"),
NET("WM_FULLSCREEN_MONITORS"),
NET("WM_NAME"),
NET("WM_PID"),
NET("WM_STRUT"),
NET("WM_STRUT_PARTIAL"),
/* States */
@ -73,6 +76,31 @@ ewmh_init(void) {
changeprop_long(&scr.root, Net("SUPPORTED"), "ATOM", supported, nelem(supported));
}
static void
tick(long id, void *v) {
static int count;
Client *c;
ulong time;
int mod, i;
time = nsec() / 1000000;
count++;
mod = count % PingPartition;
for(i=0, c=client; c; c=c->next, i++)
if(c->proto & ProtoPing) {
if(c->dead == 1 && time - c->w.ewmh.ping > PingTime) {
event("Unresponsive %#C\n", c);
c->dead++;
}
if(i % PingPartition == mod)
sendmessage(&c->w, "WM_PROTOCOLS", NET("WM_PING"), time, c->w.xid, 0, 0);
if(i % PingPartition == mod)
Dprint(DEwmh, "_NET_WM_PING %#C %,uld\n", c, time);
}
ixp_settimer(&srv, PingPeriod / PingPartition, tick, nil);
}
void
ewmh_updateclientlist(void) {
Vector_long vec;
@ -135,9 +163,6 @@ ewmh_destroyclient(Client *c) {
ewmh_updateclientlist();
e = &c->w.ewmh;
if(e->timer)
if(!ixp_unsettimer(&srv, e->timer))
fprint(2, "Badness: %#C: Can't unset timer\n", c);
free(c->strut);
}
@ -209,33 +234,6 @@ static Handlers client_handlers = {
.property = event_client_property,
};
static void
pingtimeout(long id, void *v) {
Client *c;
USED(id);
c = v;
event("Unresponsive %#C\n", c);
c->w.ewmh.ping = 0;
c->w.ewmh.timer = 0;
}
void
ewmh_pingclient(Client *c) {
Ewmh *e;
if(!(c->proto & ProtoPing))
return;
e = &c->w.ewmh;
if(e->ping)
return;
client_message(c, Net("WM_PING"), c->w.xid);
e->ping = xtime++;
e->timer = ixp_settimer(&srv, PingTime, pingtimeout, c);
}
bool
ewmh_prop(Client *c, Atom a) {
if(a == NET("WM_WINDOW_TYPE"))
@ -402,7 +400,6 @@ ewmh_setstate(Client *c, Atom state, int action) {
static bool
event_root_clientmessage(Window *w, void *aux, XClientMessageEvent *e) {
Client *c;
View *v;
ulong *l;
ulong msg;
@ -426,20 +423,14 @@ event_root_clientmessage(Window *w, void *aux, XClientMessageEvent *e) {
if(msg == xatom("WM_PROTOCOLS")) {
if(e->format != 32)
return false;
Dprint(DEwmh, "\t%A\n", l[0]);
if(l[0] == NET("WM_PING")) {
if(e->window != scr.root.xid)
return false;
c = win2client(l[2]);
if(c == nil)
return 1;
Dprint(DEwmh, "\tclient = [%#C]\"%C\"\n", c, c);
Dprint(DEwmh, "\ttimer = %ld, ping = %ld\n",
c->w.ewmh.timer, c->w.ewmh.ping);
if(c->w.ewmh.timer)
ixp_unsettimer(&srv, c->w.ewmh.timer);
c->w.ewmh.timer = 0;
c->w.ewmh.ping = 0;
if(!(w = findwin(l[2])))
return false;
w->ewmh.ping = nsec() / 1000000;
w->ewmh.lag = (w->ewmh.ping & 0xffffffff) - (l[1] & 0xffffffff);
Dprint(DEwmh, "\twindow=%W lag=%,uld\n", w, w->ewmh.lag);
return false;
}
return false;

View File

@ -55,6 +55,7 @@ void grep(char**, Reprog*, int);
char* join(char**, char*, Fmt*);
int max(int, int);
int min(int, int);
uvlong nsec(void);
char* pathsearch(const char*, const char*, bool);
void refree(Regex*);
void reinit(Regex*, char*);

View File

@ -75,8 +75,8 @@ struct ErrorCode {
struct Ewmh {
long type;
long ping;
long timer;
ulong ping;
ulong lag;
};
struct Font {

View File

@ -63,6 +63,7 @@ OBJ=\
util/max \
util/mfatal \
util/min \
util/nsec \
util/pathsearch \
util/refree \
util/reinit \

13
lib/libstuff/util/nsec.c Normal file
View File

@ -0,0 +1,13 @@
/* Written by Kris Maglione <maglione.k at Gmail> */
/* Public domain */
#include "util.h"
#include <sys/time.h>
uvlong
nsec(void) {
struct timeval tv;
gettimeofday(&tv, nil);
return (uvlong)tv.tv_sec * 1000000000 + (uvlong)tv.tv_sec * 1000;
}

View File

@ -26,7 +26,7 @@ static char** tags;
static long pid;
static long stime;
static char hostname[256];
static long nsec;
static long starttime;
typedef Window (*mapfn)(Display*, Window);
@ -84,7 +84,7 @@ init(Display *d) { /* Hrm... assumes one display... */
}
pid = getpid();
gethostname(hostname, sizeof hostname);
gethostname(hostname, sizeof hostname - 1);
}
static void
@ -102,9 +102,9 @@ setprops(Display *d, Window w) {
}
/* Kludge. */
if(nsec == 0)
nsec = time(0);
else if(time(0) > nsec + Timeout)
if(starttime == 0)
starttime = time(0);
else if(time(0) > starttime + Timeout)
return;
if(transient)

View File

@ -93,7 +93,7 @@ Event Unresponsive
client=$1; shift
msg="The following client is not responding. What would you like to do?$wi_newline"
resp=$(wihack -transient $client \
xmessage -nearmouse -buttons Kill,Wait -print
xmessage -nearmouse -buttons Kill,Wait -print \
-fn "${WMII_FONT%%,*}" "$msg $(wmiir read /client/sel/label)")
if [ "$resp" = Kill ]; then
wmiir xwrite /client/$client/ctl slay &