[gtk-win32] Windows g_socket_create_source problem
- From: Daan Nusman <d nusman re-lion com>
- To: gtk-app-devel-list gnome org, gtk-win32-list gnome org
- Subject: [gtk-win32] Windows g_socket_create_source problem
- Date: Tue, 20 Oct 2009 12:12:23 +0200
Hi everyone.
I am having some trouble combining Lua Sockets with GTK+. I'm interested
in integrating waiting for socket events in the main event loop, which
means using a GSocket-type GSource.
I think I am on the right track: I'm creating a Lua Socket, getting the
file descriptor (which is a normal fd/SOCKET), create a new GSocket
using g_socket_create_source, and attaching a callback that should fire
on data available on the socket.
The problem is that once the callback fires (i.e., when I send something
to the socket), it keeps on firing like craaayzaay, even if no data is
present on the socket. This means that the second time the callback is
called, the blocking socket will block the main thread. If I return
FALSE instead of TRUE from the callback, the first event is received
correctly, the gsource is cleaned up, but of course no other events will
be received after that.
Am I missing something or have I hit some winsock-related bug? This is
my first foray into GTK+/GLib territory, so one might never know :)
I'm using the GTK+ Windows binaries found at gtk.org (GLib 2.22.2).
Thanks,
Daan Nusman
PS. here's some source code. The addSocket function is called from Lua with
the file descriptor of the socket as argument.
//================================================
// GTK+ networking bridge
// data associated with GSource callback
struct LuaSocketData
{
lua_State* L; // the lua state that owns the callback function
int m_CallbackRef; // this is a reference to a Lua function
};
// destroys the LuaSocketData (assumes lua state still exists..)
static void LuaSocketData_destroy(gpointer data)
{
LuaSocketData* luaSocket = (LuaSocketData*)data;
luaL_unref(luaSocket->L, LUA_REGISTRYINDEX, luaSocket->m_CallbackRef);
}
// called when new data (or error) arrives on a Lua Socket.
gboolean __cdecl onLuaSocketReady(GSocket *socket,
GIOCondition condition, gpointer
user_data)
{
LuaSocketData* luaSocket = (LuaSocketData*)user_data;
lua_State* L = luaSocket->L;
if(condition == G_IO_IN)
{
printf("callback to lref#%d\n", luaSocket->m_CallbackRef);
lua_getref(L, luaSocket->m_CallbackRef);
// this calls Lua, which does a recv on the socket.
if(lua_pcall(L, 0, 0, 0))
{
printf("callback error: %s\n", lua_tostring(L, -1));
lua_pop(L, 1);
}
}
else
{
__asm int 3 //DebugBreak(); TODO
}
return TRUE; // continue receiving events
}
/*
Lua function that inserts a socket into the GTK+ event loop.
Lua params:
- 1) socket fd (use mySocket:getfd())
- 2) callback function, to be called when new data is available on
the socket
*/
static int addSocket(lua_State* L)
{
int sockFD = luaL_checkint(L, 1);
// what condition to call the callback on
GIOCondition condition = G_IO_IN;
// create new socket from the lua socket/fd
GError* err = 0;
GSocket* gSock = g_socket_new_from_fd(sockFD, &err);
if(err) luaL_error(L, "%s", err->message); // fixme: memleak
// Insert notifications into message loop,
// with special user data remembering the callback.
GSource* socketMessageSource =
g_socket_create_source(gSock, condition, NULL);
LuaSocketData* luasocketdata =
(LuaSocketData*)g_malloc(sizeof(LuaSocketData));
lua_pushvalue(L, 2);
luasocketdata->m_CallbackRef =
luaL_ref(L, LUA_REGISTRYINDEX); // store function
luasocketdata->L = lua_getmainthreadstate(L);
g_source_set_callback (socketMessageSource,
(GSourceFunc) onLuaSocketReady,
luasocketdata, g_free);
g_source_attach (socketMessageSource, NULL); // add source to "main
context"
g_source_unref (socketMessageSource);
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]