Re: g_io_channel_win32_new_messages() WaitForSingleObject()

2009-04-03 Thread Chris Vine
On Thu, 02 Apr 2009 19:49:48 -0500
Thomas Stover tho...@wsinnovations.com wrote:
 Some notes for anyone else who is just figuring out several things
 like myself:
 -a real new source would have a constructor that would do the 
 allocation and setup
 -it would also have its own functions for setting up callbacks to
 source specific events
 -I think g_source_remove_poll() would be called in related
 destructor, so I suppose the GPollFD structure needs to be stored in
 MySource as well -I guess the destructor would be the
 closer_callback of the GSourceFuncs parameter
 -the GSourceFuncs and GPollFD variables are just copied by glib when 
 they given as parameters, so they don't need to dynamic (or 
 global/static like my last examples)

I do not really understand what the issues are (that may be more my
problem than yours) but first, yes you generally would store the GPollFD
object in the source object by value if you are making your own custom
polling source, and secondly since you do need to pass g_source_new()
a GSourceFunc struct, the sensible way to implement that is to make the
GSourceFunc object (which is just a struct of function pointers common
to all source objects of that type) a static object - you don't have to,
but it would be pointless doing it any other way because you may have
more than one of the custom source objects in use at any one time which
would otherwise result in duplicated GSourceFunc objects.

Lastly, glib will correctly manage resources if you use the mechanisms
which it provides.  The finalize function you pass to GSourceFuncs
should free any MySource data which happens to have been allocated on
the heap (generally you would not have any).  Everything else will be
taken care of.  In particular g_source_attach() increments the
reference count on the source object, and after you have called
g_source_attach() you can pass ownership of the MySource object to the
main loop in the normal way by calling g_source_unref() on the MySource
source object. The main loop will then automatically destroy your
MySource object if either the dispatch function returns false, or if
g_source_remove() is called on the source id returned by
g_source_attach().  (The function you use to create your custom source
object should return this ID so that users can do just that.)

Chris

___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: g_io_channel_win32_new_messages() WaitForSingleObject()

2009-04-02 Thread Thomas Stover
Man, I'm almost there. First, just ignore everything having to do with 
win32 services. I was misreading the msdn service example. The 
WaitFor*() is really done on an event. So here is a stripped down demo 
of the progress so far. It does what I want, but then crashes before 
ending the event loop gracefully, which means something needs to be 
different. I'm sure it has something to do with the size arg to 
g_source_new() call, since GSource is simply:


typedef struct {
} GSource;

Clearly I have no idea what I even want to pass to it.

=== glib_win32_event_test.c =
#include glib.h
#include windows.h

HANDLE windows_event = NULL;
GPollFD g_poll_fd;
GSourceFuncs g_source_funcs;
int global_int = 0;

gboolean my_source_prepare(GSource *source, gint *timeout_)
{
g_print(1) my_source_prepare()\n);
*timeout_ = -1;
return FALSE;
}

gboolean my_source_check(GSource *source)
{
g_print(1) my_source_check()\n);
if(global_int)
{
 g_print(1)   bam!\n); 
 return TRUE;

}

return FALSE;
}

gboolean timeout_callback(gpointer opaq)
{
g_print(1) still here...\n);

return TRUE;
}

DWORD WINAPI thread_entry(LPVOID lpParameter)
{
g_print(2) I'm thread #%d\n, GetCurrentThreadId());
Sleep(4000);
g_print(2) stuff is going to happen now..\n);
global_int = 1;
SetEvent(windows_event);
g_print(2) I'm done\n);
return 0;
}

int main(int argc, char **argv)
{
DWORD error_code;
gchar *error_string;
GMainLoop *main_loop;
GSource *g_source;

g_print(1) I'm thread #%d\n, GetCurrentThreadId());

if((windows_event = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL)
{
 error_code = GetLastError();
 error_string = g_win32_error_message(error_code);
 g_print(1) CreateEvent() failed, \%s\\n, error_string);
 g_free(error_string);
 return 1;
}

main_loop = g_main_loop_new(NULL, FALSE);

g_timeout_add(1000, timeout_callback, NULL);
g_poll_fd.events = 0;
g_poll_fd.revents = G_IO_IN;
g_poll_fd.fd = windows_event;

memset(g_source_funcs, 0, sizeof(GSourceFuncs));
g_source_funcs.prepare = my_source_prepare;
g_source_funcs.check = my_source_check;

g_source = g_source_new(g_source_funcs, sizeof(GSource));
g_source_attach(g_source, NULL);
g_source_add_poll(g_source, g_poll_fd);

if(CreateThread(NULL, 0, thread_entry, NULL, 0, NULL) == NULL)
{
 error_code = GetLastError();
 error_string = g_win32_error_message(error_code);
 g_print(1) CreateThread() failed, \%s\\n, error_string);
 g_free(error_string);
 return 1;
}

g_main_loop_run(main_loop);
return 0;
}
 cmd.exe session output: 
1) I'm thread #3444
1) my_source_prepare()
2) I'm thread #5064
1) my_source_check()
1) still here...
1) my_source_prepare()
1) my_source_check()
1) still here...
1) my_source_prepare()
1) my_source_check()
1) still here...
1) my_source_prepare()
2) stuff is going to happen now..
2) I'm done
1) my_source_check()
1)   bam!
1) still here...
[crash and burn]
=

Thoughts?


Tor Lillqvist wrote:

It's best to experiment, as I said I don't recall the details by
heart... and too busy to actually check now.

--tml
  



___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: g_io_channel_win32_new_messages() WaitForSingleObject()

2009-04-02 Thread Thomas Stover
Well if any lone googlers ever find this, and want to know what 
happened. I did fix it with this, but I still think the right way is to 
some how create a new structure that is inherits the GSourceFuncs and 
adds a place to store the event handle and the protected data (in this 
case global_int). If there was an example of how to create a source, or 
some doc on a source life cycle, that would be helpful. I did look at 
the source, but was quickly lost. I'm guessing the main loop 
architecture involves multiple sources, fds, and realization 
callbacks all being able to exist without extras. So for instance 1 
fd could trigger 5 sources, which each result in glib calling a variable 
number of callbacks. If only there was more time to spend on these 
things


#include glib.h
#include windows.h

HANDLE windows_event = NULL;
GPollFD g_poll_fd;
GSourceFuncs g_source_funcs;
int global_int = 0;
GMainLoop *main_loop;

gboolean my_source_prepare(GSource *source, gint *timeout_)
{
g_print(1) my_source_prepare()\n);
*timeout_ = -1;
return FALSE;
}

gboolean my_source_check(GSource *source)
{
g_print(1) my_source_check()\n);
if(global_int)
{
 g_print(1)   bam!\n);
//  g_source_remove_poll(source, g_poll_fd);
 return TRUE;
}

return FALSE;
}

gboolean my_source_dispatch(GSource *source, GSourceFunc callback, 
gpointer user_data)

{
g_print(1) my_source_dispatch()\n);
if(callback == NULL)
 return FALSE;

return callback(user_data);
}

gboolean my_source_callback(gpointer data)
{
g_print(1) my_source_callback()\n);
g_main_loop_quit(main_loop);
return FALSE;
}


gboolean timeout_callback(gpointer opaq)
{
g_print(1) still here...\n);

return TRUE;
}

DWORD WINAPI thread_entry(LPVOID lpParameter)
{
g_print(2) I'm thread #%d\n, GetCurrentThreadId());
Sleep(4000);
g_print(2) stuff is going to happen now..\n);
global_int = 1;
SetEvent(windows_event);
g_print(2) I'm done\n);
return 0;
}


int main(int argc, char **argv)
{
DWORD error_code;
gchar *error_string;
GSource *g_source;

g_print(1) I'm thread #%d\n, GetCurrentThreadId());

if((windows_event = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL)
{
 error_code = GetLastError();
 error_string = g_win32_error_message(error_code);
 g_print(1) CreateEvent() failed, \%s\\n, error_string);
 g_free(error_string);
 return 1;
}

main_loop = g_main_loop_new(NULL, FALSE);

g_timeout_add(1000, timeout_callback, NULL);



g_poll_fd.events = 0;
g_poll_fd.revents = G_IO_IN;
g_poll_fd.fd = windows_event;

memset(g_source_funcs, 0, sizeof(GSourceFuncs));
g_source_funcs.prepare = my_source_prepare;
g_source_funcs.check = my_source_check;
g_source_funcs.dispatch = my_source_dispatch;

g_source = g_source_new(g_source_funcs, sizeof(GSource));
g_source_attach(g_source, NULL);
g_source_add_poll(g_source, g_poll_fd);

g_source_set_callback(g_source, my_source_callback, NULL, NULL);

if(CreateThread(NULL, 0, thread_entry, NULL, 0, NULL) == NULL)
{
 error_code = GetLastError();
 error_string = g_win32_error_message(error_code);
 g_print(1) CreateThread() failed, \%s\\n, error_string);
 g_free(error_string);
 return 1;
}

g_main_loop_run(main_loop);
return 0;
}


Thomas Stover wrote:
Man, I'm almost there. First, just ignore everything having to do with 
win32 services. I was misreading the msdn service example. The 
WaitFor*() is really done on an event. So here is a stripped down 
demo of the progress so far. It does what I want, but then crashes 
before ending the event loop gracefully, which means something needs 
to be different. I'm sure it has something to do with the size arg to 
g_source_new() call, since GSource is simply:


typedef struct {
} GSource;

Clearly I have no idea what I even want to pass to it.


___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: g_io_channel_win32_new_messages() WaitForSingleObject()

2009-04-02 Thread Chris Vine
On Thu, 02 Apr 2009 16:53:11 -0500
Thomas Stover tho...@wsinnovations.com wrote:

 
 Well if any lone googlers ever find this, and want to know what 
 happened. I did fix it with this, but I still think the right way is
 to some how create a new structure that is inherits the
 GSourceFuncs and adds a place to store the event handle and the
 protected data (in this case global_int). If there was an example of
 how to create a source, or some doc on a source life cycle, that
 would be helpful. I did look at the source, but was quickly lost. I'm
 guessing the main loop architecture involves multiple sources,
 fds, and realization callbacks all being able to exist without
 extras. So for instance 1 fd could trigger 5 sources, which each
 result in glib calling a variable number of callbacks. If only there
 was more time to spend on these things

I may be missing your point (I would have to read through the
back-posts to make sense of it), but if you want to create your own
source object to hold its own protected/private data, it is just this:

struct MySource {
  GSource source;
/* my data, such as a gpointer but it could be anything and as much member data 
as you want */  
  gpointer data;
};

It is created with:

MySource *my_source = (MySource*) g_source_new(source_funcs, sizeof(MySource));
/* initialise data */
my_source-data = my_object;

For more information see this, in particular the section Creating new
sources types:

http://library.gnome.org/devel/glib/stable/glib-The-Main-Event-Loop.html

An idle object may already do much of what you want.  With windows, I think
it uses a window event object under the hood.

Chris


___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: g_io_channel_win32_new_messages() WaitForSingleObject()

2009-04-02 Thread Thomas Stover

Chris Vine wrote:

I may be missing your point (I would have to read through the
back-posts to make sense of it), but if you want to create your own
source object to hold its own protected/private data, it is just this:

struct MySource {
  GSource source;
/* my data, such as a gpointer but it could be anything and as much member data as you want */  
  gpointer data;

};

It is created with:

MySource *my_source = (MySource*) g_source_new(source_funcs, sizeof(MySource));
/* initialise data */
my_source-data = my_object;

For more information see this, in particular the section Creating new
sources types:

http://library.gnome.org/devel/glib/stable/glib-The-Main-Event-Loop.html

An idle object may already do much of what you want.  With windows, I think
it uses a window event object under the hood.

Chris


  
Dude! Yes! Your example above needs to be in that section you reference, 
which I missed even though I've been looking at that page all day. Now 
if I could just figure out how to make the g_main_loop_quit() work with 
out first calling g_main_loop_new(). Which would make sense to me except 
g_main_loop_quit() is apparently the only function that needs the 
g_main_loop_new() call. Even g_main_loop_run() will work with a NULL. 
The relationship between main loops, main contexts, defaults, and 
manually created ones is ambiguous at best. Anyway thanks Tor and Chris.


Some notes for anyone else who is just figuring out several things like 
myself:
-a real new source would have a constructor that would do the 
allocation and setup
-it would also have its own functions for setting up callbacks to source 
specific events
-I think g_source_remove_poll() would be called in related destructor, 
so I suppose the GPollFD structure needs to be stored in MySource as well
-I guess the destructor would be the closer_callback of the 
GSourceFuncs parameter
-the GSourceFuncs and GPollFD variables are just copied by glib when 
they given as parameters, so they don't need to dynamic (or 
global/static like my last examples)



=== updated conversational source  (yes! no globals) ===
#include glib.h
#include windows.h

typedef struct {
GSource source;
HANDLE windows_event_handle;
int integer;
} MySource;

gboolean my_source_prepare(GSource *source, gint *timeout_)
{
MySource *my_source = (MySource *) source;
g_print(1) my_source_prepare()\n);
*timeout_ = -1;
return FALSE;
}

gboolean my_source_check(GSource *source)
{
MySource *my_source = (MySource *) source;
g_print(1) my_source_check()\n);
if(my_source-integer)
{
 g_print(1)   bam!\n);
 return TRUE;
}

return FALSE;
}

gboolean my_source_dispatch(GSource *source, GSourceFunc callback, 
gpointer user_data)

{
MySource *my_source = (MySource *) source;
g_print(1) my_source_dispatch()\n);
if(callback == NULL)
 return FALSE;

return callback(user_data);
}

gboolean my_source_callback(gpointer data)
{
GMainLoop *main_loop = (GMainLoop *) data;
g_print(1) my_source_callback()\n);
g_main_loop_quit(main_loop);
return FALSE;
}


gboolean timeout_callback(gpointer opaq)
{
g_print(1) still here...\n);
return TRUE;
}

DWORD WINAPI thread_entry(LPVOID lpParameter)
{
MySource *my_source = (MySource *) lpParameter;
g_print(2) I'm thread #%d\n, GetCurrentThreadId());
Sleep(4000);
g_print(2) stuff is going to happen now..\n);
my_source-integer = 1;
SetEvent(my_source-windows_event_handle);
g_print(2) I'm done\n);
return 0;
}

int main(int argc, char **argv)
{
DWORD error_code;
gchar *error_string;
GPollFD g_poll_fd;
GSourceFuncs g_source_funcs;
GMainLoop *main_loop;
MySource *my_source;

g_print(1) I'm thread #%d\n, GetCurrentThreadId());

memset(g_source_funcs, 0, sizeof(GSourceFuncs));
g_source_funcs.prepare = my_source_prepare;
g_source_funcs.check = my_source_check;
g_source_funcs.dispatch = my_source_dispatch;

my_source = g_source_new(g_source_funcs, sizeof(MySource));
g_source_attach(my_source, NULL);

main_loop = g_main_loop_new(NULL, FALSE);

g_source_set_callback(my_source, my_source_callback, main_loop, NULL);

if((my_source-windows_event_handle = CreateEvent(NULL, TRUE, FALSE, 
NULL)) == NULL)

{
 error_code = GetLastError();
 error_string = g_win32_error_message(error_code);
 g_print(1) CreateEvent() failed, \%s\\n, error_string);
 g_free(error_string);
 return 1;
}

my_source-integer = 0;
g_poll_fd.events = 0;
g_poll_fd.revents = G_IO_IN;
g_poll_fd.fd = my_source-windows_event_handle;
g_source_add_poll(my_source, g_poll_fd);

g_timeout_add(1000, timeout_callback, NULL);

if(CreateThread(NULL, 0, thread_entry, (LPVOID) my_source, 0, NULL) == 
NULL)

{
 error_code = GetLastError();
 error_string = g_win32_error_message(error_code);
 g_print(1) CreateThread() failed, \%s\\n, error_string);
 g_free(error_string);
 return 1;
}

g_main_loop_run(main_loop);
return 0;
}
===

--
www.thomasstover.com

___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org

Re: g_io_channel_win32_new_messages() WaitForSingleObject()

2009-04-01 Thread Tor Lillqvist
 normal HANDLE and a waitable one even, that can be passed to
 WaitForSingleObject() and friends, then it should work to use it as
 the fd in a GPollFD.

 typedef struct {

 #if defined (G_OS_WIN32)  GLIB_SIZEOF_VOID_P == 8
  gint64 fd;
 #else
  gint           fd;

 ok so on windows fd here is a pointer to a handle,

Not a pointer to a HANDLE, but a HANDLE as such. (And it must be a
waitable handle.)

 not the rutime lib's lookup table's integer index...

You mean the C library's file descriptors? Indeed not. To use them,
you need to use g_io_channel_win32_new_fd(). (Which then creates a
GIOChannel, not a GPollFD. And it works only if your code uses the
same C library as GLib does, normally msvcrt.dll.)

 any ideas what the revents mask should be?

G_IO_IN I think.

 Very interesting. So presumably on windows poll() is really something like
 WaitForMultiple*()?

Exactly. Check in gpoll.c.

 Which would mean what - a prepare that always returns
 FALSE w/ *timeout_ = 0, and a check that does what it what otherwise do if
 WaitForSingleObject() returned hot?

It's best to experiment, as I said I don't recall the details by
heart... and too busy to actually check now.

--tml
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


g_io_channel_win32_new_messages() WaitForSingleObject()

2009-03-31 Thread Thomas Stover
Anyone know if you can use a win32 message io channel on arbitrary 
handles or just gdi windows or whatever the intended use of that is? I 
openly admit a don't get windows at all, so this maybe just really out 
there. Specifically, if I had handle returned from 
RegisterServiceCtrlHandler() (which as best as I can imagine in my linux 
centric reality is some sort alertable mutex like a futex) there are 
msdn examples showing WaitForSingleObject() used as an alternative to 
global variable polling. I'm just wondering if there is a path to glib 
event loop integration other than a timer and with an if statement inside.


For those of you who never have to look at windows just use the above to 
make yourselves feel better today. For those of you that make all this 
stuff work on windows, I am truly grateful.

___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: g_io_channel_win32_new_messages() WaitForSingleObject()

2009-03-31 Thread Tor Lillqvist
 Anyone know if you can use a win32 message io channel on arbitrary handles

Nope. It is just for window messages for the window indicated by the
HWND parameter.

 Specifically, if I had handle returned from RegisterServiceCtrlHandler()
 (which as best as I can imagine in my linux centric reality is some sort
 alertable mutex like a futex) there are msdn examples showing
 WaitForSingleObject() used as an alternative to global variable polling.

I have never used that service control API, no idea what it is used for even...

But if MSDN says that the returned SERVICE_STATUS_HANDLE actually is a
normal HANDLE and a waitable one even, that can be passed to
WaitForSingleObject() and friends, then it should work to use it as
the fd in a GPollFD.

Unfortunately I don't actually know or understand the glib main loop
API very well by heart, so I can't say off-hand what you then should
do with such a GPollFD. Pass it to g_source_add_poll(), but for what
GSource? You might need to implement your own GSource type with
relevant callbacks to take care of that handle firing, and then pass
such a GSource object to g_source_attach()? Sorry...

--tml
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: g_io_channel_win32_new_messages() WaitForSingleObject()

2009-03-31 Thread Thomas Stover

Tor Lillqvist wrote:

I have never used that service control API, no idea what it is used for even...
  

oh, just the needlessly complex, 75 step, windows' equivalent to daemon()


But if MSDN says that the returned SERVICE_STATUS_HANDLE actually is a
normal HANDLE and a waitable one even, that can be passed to
WaitForSingleObject() and friends, then it should work to use it as
the fd in a GPollFD.
  

typedef struct {

#if defined (G_OS_WIN32)  GLIB_SIZEOF_VOID_P == 8
 gint64 fd;
#else
 gint   fd;
#endif
 gushortevents;
 gushortrevents
} GPollFD;


ok so on windows fd here is a pointer to a handle, not the rutime lib's 
lookup table's integer index...

any ideas what the revents mask should be?


Unfortunately I don't actually know or understand the glib main loop
API very well by heart, so I can't say off-hand what you then should
do with such a GPollFD. Pass it to g_source_add_poll(), but for what
GSource? You might need to implement your own GSource type with
relevant callbacks to take care of that handle firing, and then pass
such a GSource object to g_source_attach()? Sorry...

--tml
  

typedef struct {

 gboolean (*prepare)  (GSource*source,
gint   *timeout_);
 gboolean (*check)(GSource*source);
 gboolean (*dispatch) (GSource*source,
GSourceFunc callback,
gpointeruser_data);
 void (*finalize) (GSource*source); /* Can be NULL */

 /* For use by g_source_set_closure */
 GSourceFunc closure_callback;	   
 GSourceDummyMarshal closure_marshal; /* Really is of type GClosureMarshal */

} GSourceFuncs;


Very interesting. So presumably on windows poll() is really something 
like WaitForMultiple*()? Which would mean what - a prepare that always 
returns FALSE w/ *timeout_ = 0, and a check that does what it what 
otherwise do if WaitForSingleObject() returned hot?


I'm going to try somethings...

---
ww.thomasstover.com

___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list