Re: g_source_add_poll or g_io_add_watch in Windows?



Tor Lillqvist wrote:
Another possibility is to restructure the code and use
g_io_add_watch() and g_io_remove_watch() instead.

I didn't realise there was a g_io_remove_watch - I don't think it's in the
documentation.

Ah;) I meant g_source_remove()...

--tml

Yes - it works under Windows using g_io_add_watch() and g_source_remove() :) - Thanks

My code is listed below. I am interested in any feedback on other approaches, efficiency, etc. that would work under Windows as well as Linux.

For my application I only need to be able to turn off polling when "badly behaving" clients are encountered. For a collection of clients that consume messages reasonably quickly (the normal case) then it's not necessary to turn off polling.

My Channel structure contains a GIOChannel as well as other stuff - e.g. specific callbacks for reading/writing and deleting.

The original idea came from someone on this mailing list some time ago.

Peter Robinson

-------- channel_watch.h ------------------------------------------------------------
/*
 Copyright (C) 2006, 2007, 2008 Peter Robinson
 Email: pjr itee uq edu au

 This library is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
#ifndef CHANNEL_WATCH_H
#define CHANNEL_WATCH_H

G_BEGIN_DECLS

typedef struct _ChannelWatch ChannelWatch;

struct _ChannelWatch {
gpointer chanptr; guint sourceid;
 gint events;
};

/* Create a new channel watch */
ChannelWatch* channel_watch_new(gpointer chan);

/* Destroy the channel watch */
void channel_watch_destroy(ChannelWatch *chanwatch);

/* Allow polling on input - i.e. add G_IO_IN to events */
void channel_watch_setInPoll(ChannelWatch *chanwatch);

/* Remove polling on input */
void channel_watch_unsetInPoll(ChannelWatch *chanwatch);

/* Allow polling on output - i.e. add G_IO_OUT to events */
void channel_watch_setOutPoll(ChannelWatch *chanwatch);

/* Remove polling on output */
void channel_watch_unsetOutPoll(ChannelWatch *chanwatch);


G_END_DECLS

#endif

-------- channel_watch.c ------------------------------------------------------------
/*
 Copyright (C) 2006, 2007, 2008 Peter Robinson
 Email: pjr itee uq edu au

 This library is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
#include <glib.h>
#include <stdio.h>

#include "channel.h"

/* Management of sockets - sets and unsets watches on GIOChannels */

/* The callback for g_io_add_watch */
gboolean watch_callback(GIOChannel *source, GIOCondition condition,
                   gpointer data)
{
 Channel* chan = (Channel *)data;
 if (condition & G_IO_HUP) {
   initDestroy(chan);
   return TRUE;
 }
 if  (condition & chan->watch->events & G_IO_IN) {
   incallback(chan);
 }
 if (condition & chan->watch->events & G_IO_OUT) {
   outcallback(chan);
 }
 return TRUE;
}

/* Create a new channel watch */
ChannelWatch* channel_watch_new(gpointer chan)
{
 ChannelWatch* watch = g_new(ChannelWatch, 1);
 watch->chanptr = chan;
 watch->events = G_IO_IN | G_IO_HUP;
watch->sourceid = g_io_add_watch(((Channel *)chan)->channel, watch->events,
                                  watch_callback,chan);
 return watch;
}

/* Destroy the channel watch */
void channel_watch_destroy(ChannelWatch *chanwatch)
{
 g_source_remove(chanwatch->sourceid);
 g_free(chanwatch);
}

/* Allow polling on input - i.e. add G_IO_IN to events */
void channel_watch_setInPoll(ChannelWatch *watch)
{
 if (watch->events & G_IO_IN) return;

 watch->events |= G_IO_IN;
 g_source_remove(watch->sourceid);
 Channel * chan = (Channel *)watch->chanptr;
 watch->sourceid = g_io_add_watch(chan->channel, watch->events,
                                  watch_callback,chan);
}

/* Remove polling on input */
void channel_watch_unsetInPoll(ChannelWatch *watch)
{
 if (watch->events & G_IO_IN) {
   watch->events &= ~G_IO_IN;
   g_source_remove(watch->sourceid);
   Channel * chan = (Channel *)watch->chanptr;
   watch->sourceid = g_io_add_watch(chan->channel, watch->events,
                                    watch_callback,chan);
 }
}

/* Allow polling on output - i.e. add G_IO_OUT to events */
void channel_watch_setOutPoll(ChannelWatch *watch)
{
 if (watch->events & G_IO_OUT) return;

 watch->events |= G_IO_OUT;
 g_source_remove(watch->sourceid);
 Channel * chan = (Channel *)watch->chanptr;
 watch->sourceid = g_io_add_watch(chan->channel, watch->events,
                                  watch_callback,chan);

}

/* Remove polling on output */
void channel_watch_unsetOutPoll(ChannelWatch *watch)
{
 if (watch->events & G_IO_OUT) {
   watch->events &= ~G_IO_OUT;
   g_source_remove(watch->sourceid);
   Channel * chan = (Channel *)watch->chanptr;
   watch->sourceid = g_io_add_watch(chan->channel, watch->events,
                                    watch_callback,chan);
}
}

----------------------------------------------------------------------------------------------------


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]