47919

msgrcv - SA_RESTART flag doesn't work

Question:

There is something wrong with my code that uses IPC queue to communicate between threads. I need to handle SIGINT safely - let program finish all active threads when SIGINT appeared before shutting down. Though, I have serious problem of finding solution because even with sigaction for SIGINT with flag SA_RESTART the msgrcv function is getting EINTR error.

My question is - is there any way to avoid EINTR with msgrcv function other than specifying the error condition in some "if" such as:

if (msgrcv<0){ if (errno == EINTR){ errno = 0; } }

Here is really simplified version of my program to demonstate problem :

#include <stdlib.h> #include <stdio.h> #include <signal.h> #include <sys/msg.h> #define IPC_KEY 11000 #define BUF_SIZE 128 //structure of IPC message typedef struct msgbuf{ long mtype; char mtext[BUF_SIZE]; } message_buf; void handle_sigint(int sig){ signal(SIGINT,SIG_IGN); /* some operation to handle sigint, here it's really simple setting SIGINT to be ignored */ } int main(){ long ipc_id; message_buf msg; struct sigaction setup_action; sigset_t block_mask; //setup sigaction for SIGINT sigemptyset(&block_mask); sigaddset(&block_mask,SIGINT); setup_action.sa_handler = handle_sigint; setup_action.sa_mask = block_mask; setup_action.sa_flags = SA_RESTART; if (sigaction(SIGINT, &setup_action, 0) < 0){ perror("sigaction"); exit(1); } //creating the ipc queue if ((ipc_id = msgget(IPC_KEY, IPC_CREAT | IPC_EXCL | 0666))<0){ perror("error in msgget"); exit(1); } for(;;){ if (msgrcv(ipc_id,&msg,BUF_SIZE,1,0)<0){ perror("error in msgrcv"); exit(1); } printf("received message : %s\n",msg.mtext); } }

And here is simple program to clean up the IPC queue :

#include <stdlib.h> #include <stdio.h> #include <signal.h> #include <sys/msg.h> #define IPC_KEY 11000 int main(){ long ipc_id; if ((ipc_id = msgget(IPC_KEY, IPC_CREAT | 0666 )) < 0) { perror("error in msgget"); exit(1); } if (msgctl(ipc_id, IPC_RMID, 0) != 0){ perror("error in msgctl"); exit(1); } return 0; }

Thanks in advance for help! I really hope I didn't make duplicate question but I tried to look for a while for a solution and unfortunately didn't find any other than explicitly catching EINTR errno with if function.

Answer1:

From the <a href="http://man7.org/linux/man-pages/man7/signal.7.html" rel="nofollow">(Linux) manual</a>:

<blockquote>

The following interfaces are never restarted after being interrupted by a signal handler, regardless of the use of SA_RESTART; they always fail with the error EINTR when interrupted by a signal handler:

....

<ul><li>System V IPC interfaces: <strong>msgrcv(2)</strong>, msgsnd(2), semop(2), and semtimedop(2).</li> </ul></blockquote>

The way SA_RESTART is handled is a bit implementation defined. You didn't tag with a specific Unix flavor but I assume your Unix simply doesn't obey SA_RESTART for your specific system call.

Answer2:

@cnicutar beat me to that by 10 seconds (so +1), but I'd add that all you need to do is to wrap the call to msgrcv in a do/while loop, e.g.

int res; do { res = msgrcv(your parameters here); } while ((res < 0 ) && (errno == EINTR));

You can of course define a tiny function to do that for you if you use msgrcv a lot.

Recommend

  • Passing Datas from cshtml to custom edit for not working
  • How to send request from iOS (Swift) to Dialogflow V2 API without Cloud Functions?
  • Consume latest value from a topic for each keys
  • How to get the screenshot of a minimized application programmatically?
  • How to use use_library('django','1.2')
  • how to count the number of state change in pandas?
  • How to disable the wired headset programmatically in Java
  • Node.js on Google Cloud Platform Pub/Sub tutorial worker is failing with “TypeError: Cannot call met
  • Return type in demangled member function name
  • Magento - Breadcrumbs on category page
  • Visibility hidden removes background color in a table [duplicate]
  • Do basic math inside Hiera
  • removing Hebrew “niqqud” using r
  • ActionBar is hiding when keyboard appears
  • Force GPU memory limit in PyTorch
  • Textarea editor Redactor. Insert value with jQuery
  • Find out the size of a polymorphic object
  • 'SSL Stream Failed to Authenticate as Client' in APNS sharp
  • Ideas for how to make a date separator (Today/Tomorrow) for a mail inbox like application?
  • Accessing an Ember.Mixin within a custom handlebars helper
  • Graph coloring Gurobi constraints
  • ASP.NET Core Sharing Identity Cookie across azure web apps on default domain (*.azurewebsites.net)
  • FCM | Multiple Sender ID [duplicate]
  • Transform a Multipolygon SF object in R from XY coordinates to lat/lon
  • Two way binding not working in ng-bootstrap radio button in an angular reactive form
  • Get method parameters with specific annotation in aspect in scala using java reflection
  • C++ method declaration including a macro
  • When scaling and drawing an image to canvas in iOS Safari, width is correct but height is squished
  • Multiple custom authentication with spring security
  • what is a good structure to save this data
  • Android: Mediaplayer stop / start playing raw resource
  • Passing HTTP Post from AWS API GW to Lambda
  • How to implement Google Drive and Google Plus sdk in ios project
  • Query regarding com.jcraft.jsch.JSchException: UnknownHostKey: x.y.com. DSA key fingerprint is “ac:e
  • System.Drawing.DrawString() weird wrapping of long string
  • Query takes almost two seconds but matches only two rows - why isn't the index helping?
  • openpyxl - adding new rows in excel file with merged cell existing
  • Error handeling in antlr 3.0
  • What does the “id” field in an Android “Google Play Music” broadcast intent correspond to?