Correct thread function typing for use with g_thread_new() in C language?

Viewed 43

I have written a multi-threaded program that works, but throws warnings at compile-time.

The header file contains the definition of a struct which contains data, as well as the thread function prototype:

//=============main.h=============
// Main data structure definition
typedef struct _SPSData SPSData;
struct _SPSData {
  GtkWidget *main_window;
  GtkWidget *menubar1;
  GtkWidget *view;
  GtkWidget *parent;  // Pointer to parent that spawned an error. e.g., data->menubar1, data->main_window, or data->traceroute_window

  char *error_text;  // String to hold error messages.
  char *warning_text;  // String to hold warning messages.

  etc.
};

// Thread function prototype
int ipv4_send (SPSData *);

The thread function to be started by g_thread_new() looks like:

//==========ipv4_send.c=============
int ipv4_send (SPSData *data)
{ 
  
  some error detection
  if error {
    return (EXIT_FAILURE);
  }
  
  Send ipv4 stuff.

  return (EXIT_SUCCESS);
}

And there's a callback from the UI which invokes ipv4_send() via g_thread_new():

//==========callbacks.c=======
// Send packet(s)
int on_button1_clicked (GtkButton *button1, SPSData *data)
{
  (void) button1;  // This statement suppresses compiler warning about unused parameter.

  GThread *thread;

  // Spawn thread to send IPv4 packet(s).
  thread = g_thread_new ("ipv4_send", (GThreadFunc) ipv4_send, data);
  if (! thread) {
    fprintf (stderr, "Error: Unable to create new thread for ipv4_send() in on_button1_clicked().\n");
    exit (EXIT_FAILURE);
  }

  return (EXIT_SUCCESS);
}

On compilation, I receive the warning:

callbacks.c: In function ‘on_button1_clicked’:
callbacks.c:3846:41: warning: cast between incompatible function types from ‘int (*)(SPSData *)’ {aka ‘int (*)(struct _SPSData *)’} to ‘void * (*)(void *)’ [-Wcast-function-type]
 3846 |     thread = g_thread_new ("ipv4_send", (GThreadFunc) ipv4_send, data);

Should the thread function be defined as follows?

==========ipv4_send.c=============
int *ipv4_send (SPSData *data)
{
 etc.

with corresponding change to the prototype:

// Thread function prototype
int *ipv4_send (SPSData *);

I don't know how to implement that, as my return statements would be incorrect.

In summary, I don't know how to make my function conform to the expected GThreadFunc typing.

1 Answers

Here is the answer as I interpreted what Cheatah said in the comments. This works perfectly and the compiler is no longer throwing warnings.

The header file contains the definition of a struct which contains data, as well as the thread function prototype:

//=============main.h=============
// Main data structure definition
typedef struct _SPSData SPSData;
struct _SPSData {
  GtkWidget *main_window;
  GtkWidget *menubar1;
  GtkWidget *view;
  GtkWidget *parent;  // Pointer to parent that spawned an error. e.g., data->menubar1, data->main_window, or data->traceroute_window

  char *error_text;  // String to hold error messages.
  char *warning_text;  // String to hold warning messages.

  etc.
};

// Thread function prototype (consistent with GThreadFunc).
void * ipv4_send (void *);

The thread function to be started by g_thread_new() looks like:

//==========ipv4_send.c=============
void *ipv4_send (void *pointer)
{ 
  struct _SPSData *data;
  data = (SPSData *) pointer;
  
  some error detection
  if error {
    return (pointer);
  }
  
  Send ipv4 stuff.

  return (pointer);
}

And there's a callback from the UI which invokes ipv4_send() via g_thread_new():

//==========callbacks.c=======
// Send packet(s)
int on_button1_clicked (GtkButton *button1, SPSData *data)
{
  (void) button1;  // This statement suppresses compiler warning about unused parameter.

  GThread *thread;

  // Spawn thread to send IPv4 packet(s).
  thread = g_thread_new ("ipv4_send", (GThreadFunc) ipv4_send, data);
  if (! thread) {
    fprintf (stderr, "Error: Unable to create new thread for ipv4_send() in on_button1_clicked().\n");
    exit (EXIT_FAILURE);
  }

  return (EXIT_SUCCESS);
}

Thank you, Cheatah!

Related