[gccsdk] UnixLib, Signals & Threading

Adam lists at snowstone.org.uk
Wed Jul 2 13:55:14 PDT 2008


In message <f25c7bb84f.admin at snowstone.org.uk>, Adam  wrote:

> In message <9b5e37b84f.Jo at hobbes.bass-software.com>, John Tytgat  wrote:

> > An as simple as possible running example demonstrating your question
> > could help us.
> 
> OK, I'll try and create a self-contained example, though the
> combination of threads and signal handlers means it won't be that
> small :(

OK, I've hacked out the relevant bits from my app and attached the
result to this message. It requires DeskLib to link with and Reporter to
be loaded for debug output. Click right button on the iconbar icon to
quit and left button to generate a signal. I'm trying to get the "I want
to see this message" words to appear in the Reporter output when the
signal is generated.

Thanks,
Adam

P.S. Sorry, I should have said before, I'm using GCC 3.4.6R3

-- 
Adam Richardson          Carpe Diem
http://www.snowstone.org.uk/riscos/
-------------- next part --------------
/* gcc -mthrowback -o SigTest DeskLib:DeskLibU.o sigtest.c */

#include <pthread.h>
#include <signal.h>
#include <stdlib.h>

#include "DeskLib:SWI.h"
#include "DeskLib:Event.h"
#include "DeskLib:Icon.h"

#define NO_SIGNAL -1

BOOL go = TRUE;
int signal_handled = NO_SIGNAL;
pthread_mutex_t signal_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_t tid;


void Report(const char *text)
{
  SWI(1 ,0 , SWI_Reporter_Text0 | XOS_Bit, text);
}

BOOL BT_Null_Handler(event_pollblock *event, void *reference)
{
  UNUSED(event);
  UNUSED(reference);

  pthread_yield();

  if (signal_handled != NO_SIGNAL)
  {
    Report("I want to see this message");
    pthread_mutex_lock(&signal_mutex);
    signal_handled = NO_SIGNAL;
    pthread_mutex_unlock(&signal_mutex);
    abort();
  }

  /* Null event stuff goes here */

  return TRUE;
}

void *BT_Signal_Catcher(void *vptr_args)
{
  sigset_t signal_set;
  int sig;

  while(go)
  {
    /* Wait for any signal */
    sigfillset(&signal_set);
    Report("SigThrd: going to sleep...");
    sigwait(&signal_set, &sig);
    Report("SigThrd: woken up!");

    /* Set value, which is tested in null handler */
    pthread_mutex_lock(&signal_mutex);
    signal_handled = sig;
    pthread_mutex_unlock(&signal_mutex);
  }

  pthread_exit(NULL);
}

BOOL BT_IconBar_Handler(event_pollblock *event, void *reference)
{
  UNUSED(reference);


  if (event->data.mouse.button.data.menu)
  {

    return TRUE;
  }
  else if (event->data.mouse.button.data.select)
  {
    int* ptr = (int*)0;
    Report("Generating signal");
    *ptr = 1;
    return TRUE;
  }
  else if (event->data.mouse.button.data.adjust)
  {
    go=FALSE;
    return TRUE;
  }

  return FALSE;
}

int main(int argc, char *argv[])
{
  sigset_t signal_set;
  char buffer[256];
  icon_handle baricon;

  Report("\\bSigTest starting up...");

  Event_InitNested("SigTest");

  /* Block all signals */
  sigfillset(&signal_set);
  pthread_sigmask(SIG_BLOCK, &signal_set, NULL);

  /* Signal handler thread */
  if (pthread_create(&tid, NULL, &BT_Signal_Catcher, "Signal Thread"))
    abort();


  /* Create other threads here */


  strcpy(buffer, "!UnixHome");
  baricon = Icon_BarIcon(buffer, iconbar_RIGHT);

  /* Iconbar event handler */
  Event_Claim(event_CLICK, window_ICONBAR, event_ANY, BT_IconBar_Handler, NULL);

  /* Null handler (required to keep threads active & also act on thread outcomes) */
  Event_Claim(event_NULL, event_ANY, event_ANY, BT_Null_Handler, NULL);

  /* Poll loop */
  while(go) Event_PollIdle(20);

  Report("SigTest closing down");

  return 0;
}




More information about the gcc mailing list