Re: g_io_channel_win32_new_messages() & WaitForSingleObject()
- From: Thomas Stover <thomas wsinnovations com>
- To: Chris Vine <chris cvine freeserve co uk>
- Cc: Tor Lillqvist <tml iki fi>, gtk-app-devel-list gnome org
- Subject: Re: g_io_channel_win32_new_messages() & WaitForSingleObject()
- Date: Thu, 02 Apr 2009 19:49:48 -0500
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
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]