Re: [Iup-users] Proper usage of IupPostMessage when using Lua - example needed.

2022-05-25 Thread Eric Wing
On 5/24/22, Stefan Heinzmann  wrote:
> Hello list,
>
> The documentation mentions in passing that IupPostMessage is expected to
> be thread safe, which I take to mean that it can be called from any
> other thread than the thread running the IUP main loop, without needing
> any synchronization.
>
> I would like to do that with Lua rather than C, and I wonder how it is
> done in practice. I would appreciate a tutorial example that shows how I
> can invoke iup.PostMessage from other threads without risking threading
> mishaps.
>
> Thanks!
>
> Stefan

I helped implement IupPostMessage. In simplified terms, the way it
works is that it uses the underlying OS APIs to post a message to the
native event loop queue. Then back on the main thread, when the native
event comes up at the top of the queue for handling, IUP then invokes
your callback function (which is now being invoked/run on the main UI
thread).

So simply, you can call IupPostMessage from any thread, and the
callback will always happen some time later on the main thread.

Additionally, if the message you post is just primitive types (in C,
e.g. int, double), then there is no locking needed to protect the data
since the posted message is a copy. But if you pass pointers through
IupPostMessage and modify things, then you still need to give
consideration to what happens if multiple threads are modifying the
shared data.

In Lua, it should be the same thing. IupPostMessage won't directly
cause any threading issues, but ultimately, any threading mishaps will
be caused by mishaps with shared state across your different threads,
which is probably more likely going to be the result of what's going
on in the rest of your program and not IupPostMessage itself. (For
example, while Lua does not care what thread it is run on, it is not
safe to concurrently run the same Lua state on multiple threads at the
same time, so whatever mechanism you use to multithread with Lua needs
to deal with this.)

-Eric


___
Iup-users mailing list
Iup-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/iup-users


Re: [Iup-users] Proper usage of IupPostMessage when using Lua - example needed.

2022-05-25 Thread Antonio Scuri
  Sorry, I only have a sample in C. It is attached.

  In Lua you will  need something likeluathread too.

Best,
Scuri


Em ter., 24 de mai. de 2022 às 14:35, Stefan Heinzmann <
stefan_heinzm...@gmx.de> escreveu:

> Hello list,
>
> The documentation mentions in passing that IupPostMessage is expected to
> be thread safe, which I take to mean that it can be called from any
> other thread than the thread running the IUP main loop, without needing
> any synchronization.
>
> I would like to do that with Lua rather than C, and I wonder how it is
> done in practice. I would appreciate a tutorial example that shows how I
> can invoke iup.PostMessage from other threads without risking threading
> mishaps.
>
> Thanks!
>
> Stefan
>
>
> ___
> Iup-users mailing list
> Iup-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/iup-users
>
#include 
#include 
#include "iup.h"
#include "iupcbs.h"

static Ihandle *timer1;
static Ihandle *button;

static int postmessage_cb(Ihandle *ih, char* s, int i, double d)
{
//  IupLog("DEBUG", "In postmessage_cb\n");
  IupLog("DEBUG", "In postmessage_cb, ih:%p, sp:%p, s:%s, i:%d, d:%lf\n", ih, 
s, s, i, d);
  int is_active = IupGetInt(ih, "ACTIVE");
  IupSetInt(ih, "ACTIVE", !is_active);

  static int flip = 0;
  if(flip)
  {
IupSetAttribute(ih, "TITLE", "BUTTON");
  }
  else
  {
IupSetAttribute(ih, "TITLE", "button");
  }
  flip = !flip;

  return IUP_DEFAULT;
}

static int timer_cb(Ihandle *ih)
{
  IupPostMessage(button, NULL, 0, 0);
//  IupPostMessage(button, "foo", (int)(intptr_t)ih, (double)(intptr_t)ih);
  return IUP_DEFAULT;
}

//#define USE_PTHREADS 1
#define USE_PTHREADS 0
#if USE_PTHREADS
#include 
#include 
#include 

void* thread_main(void* param)
{
  while(1)
  {
usleep(4000*1000);
IupPostMessage(button, "foo", (int)(intptr_t)button, 
(double)(intptr_t)button);
  }
}

void PostMessageTest(void)
{
  Ihandle *dlg;
  button = IupButton("Button", NULL);
  // button = IupLabel("Button"); // hack because we haven't finished 
implementing all the button features for IupEmscripten yet
  IupSetCallback(button, "POSTMESSAGE_CB", (Icallback)postmessage_cb);
  dlg = IupDialog(button);
  IupSetAttribute(dlg, "TITLE", "IupPostMessage Test");
  IupSetAttribute(dlg, "SIZE", "200x100");
  IupShow(dlg);

  pthread_attr_t attr;
  pthread_attr_init();
  pthread_attr_setdetachstate(, PTHREAD_CREATE_JOINABLE);
  pthread_t thread;
  int rc = pthread_create(, , thread_main, 0);
}

#else


void PostMessageTest(void)
{
  Ihandle *dlg;
  button = IupButton("Button", NULL);
  IupSetCallback(button, "POSTMESSAGE_CB", (Icallback)postmessage_cb);
  dlg = IupDialog(button);
  IupSetAttribute(dlg, "TITLE", "IupPostMessage Test");
  IupSetAttribute(dlg, "SIZE", "200x100");

  IupShow(dlg);
  timer1 = IupTimer();
  IupSetAttribute(timer1, "TIME",  "4000");
  IupSetAttribute(timer1, "RUN",   "YES");
  IupSetCallback(timer1, "ACTION_CB", (Icallback)timer_cb);
}
#endif

#ifndef BIG_TEST
#ifndef IUP_LEGACY

void IupExitPoint()
{
IupClose();
}

void IupEntryPoint()
{
IupSetFunction("EXIT_CB", (Icallback)IupExitPoint);
PostMessageTest();
}


int main(int argc, char * argv[])
{
IupOpen(0, NULL);
IupSetFunction("ENTRY_POINT", (Icallback)IupEntryPoint);
IupMainLoop();
}



#else
int main(int argc, char* argv[])
{
  IupOpen(, );

  PostMessageTest();

  IupMainLoop();

  IupClose();

  return EXIT_SUCCESS;
}
#endif
#endif
___
Iup-users mailing list
Iup-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/iup-users