Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gpioTerminate() leaves signal handlers installed #341

Closed
frank1119 opened this issue Apr 24, 2020 · 12 comments · Fixed by #365
Closed

gpioTerminate() leaves signal handlers installed #341

frank1119 opened this issue Apr 24, 2020 · 12 comments · Fixed by #365

Comments

@frank1119
Copy link

frank1119 commented Apr 24, 2020

After calling gpioTerminate() the signal handlers are still installed. Maybe something like this should be done afterwards to cleanup?

for(int sig = PI_MIN_SIGNUM; sig <= PI_MAX_SIGNUM; sig++)
{
    struct sigaction sa;

    sigemptyset(&sa.sa_mask);
    sa.sa_handler = SIG_DFL;
    sa.sa_flags   = 0;

    sigaction(sig, &sa, NULL);
}

Or, maybe a lot better:

static struct sigaction sao[PI_MAX_SIGNUM - PI_MIN_SIGNUM + 1];

static void sigSetHandler(void)
{
   int i;
   struct sigaction new;

   for (i=PI_MIN_SIGNUM; i<=PI_MAX_SIGNUM; i++)
   {

      memset(&new, 0, sizeof(new));
      new.sa_handler = sigHandler;

      sigaction(i, &new, &sao[i - PI_MIN_SIGNUM]);
   }
}

static void sigUnsetHandler(void)
{
   int i;

   for (i=PI_MIN_SIGNUM; i<=PI_MAX_SIGNUM; i++)
      sigaction(i, &sao[i - PI_MIN_SIGNUM], NULL);
}

void gpioTerminate(void)
{
   // Original code
   ....
   // End original code
   sigUnsetHandler();
}
@guymcswain
Copy link
Collaborator

Is there a particular problem that you are trying to solve and is there a proposed solution that you have tested?

@frank1119
Copy link
Author

I have a little project on a Pi Zero. I use libgpiod for processing the gpio lines going from 0 to 1 and reverse, but because libgpiod has no support (for kernel 4.x that is) for changing the PullUp/PullDown resistors, I initialize these with pigpio. I use pigpio because this project is alive and being maintained.

Pseudo code:

gpioInitialize();
/* set pullups */
gpioTerminate();

/* set up libgpiod */

sleep(forever);

/* terminate libgpiod */

When you compile the 'code' in a console project (I run the Pi headless), then run the executable and press Ctrl-Z during the sleep() (to pause the program), the signalhandler of pigpio will step in, tell you that the signal is not being handled and terminate the program.
In fact, this behavior occurs always after calling gpioInitialize(). This pseudo code has the same effect:

gpioInitialize();
sleep(forever or a little less);
gpioTerminate();

In my humble opinion, because it's not that I want to criticize anyone or anything, this leaves some questions:

  1. When a library (e.g. pigpio) uses resources, and a terminating function is supplied, should this library not cleanup all used resources?
  2. Why is a signal handler installed by gpioInitialize() for signals that are not going to be handled anyway?

When you say: "Not many people are using pigpio for such a brief time, but for the full duration of their program, so probably gpioTerminate() will only be called just before terminating their whole program, if it will be called at all", you are right. I agree with you that solving question 1 is not very useful or important for most people. Implementing the code I suggested would only be a matter of correctness or politeness.
But the behavior questioned by question 2 also affects people who use pigpio the 'normal' way. For that behavior, I agree that my code does not solve anything.

I think that the issue I report is not very well described. In hindsight is should be: 'Pressing Ctrl-z while using pigpio terminates the running process' .

I hope this clarifies my issue.

@guymcswain
Copy link
Collaborator

Thanks for the additional background. My questions were aimed at 'what is it that want implemented' - you gave multiple choices - and 'how to know it is working'.

Also, have you done any research on the history of issues relating to signal handling on this repo. I'm asking because I'm not an expert in this area and you seem to be more knowledgeable. I do know that an option to turn off signal handling was implemented. Don't know if you experimented with that.

@frank1119
Copy link
Author

frank1119 commented May 2, 2020

I do know that an option to turn off signal handling was implemented

I have missed this one. Can you point out to me how to accomplish this?

By the way: For my own project I've multiple workarounds: e.g. I could save the signal handlers before initializing pigpio and restore them after terminating pigpio. I could leave pigpio altogether (for this project that is) and use the bcm2835 library from Mike McCauley, just for doing the same thing as I used pigpio for. Another workaround would be to 'install' the PullUp resistors at boot time in the /boot/config.txt, so I'm not desperate :-).

With regards to doing research: What I can find about this issue is that quite some people are fighting this issue, so that brings me back to question 2, but it is not my intention to corner you about this issue.

@guymcswain
Copy link
Collaborator

guymcswain commented May 2, 2020

The api is gpioCfgInternals and the value is PI_CFG_NOSIGHANDLER (1<<10). Not so easily found. I had to look in source.

What I can find about this issue is that quite some people are fighting this issue, so that brings me back to question 2

Yes and if you read all the related threads you'll find that Joan defends the rationale behind the implementation. I can't remember but it has something to do with the daemonization process.

@frank1119
Copy link
Author

frank1119 commented May 2, 2020

Nice. I just did the same. I agree with you: PI_CFG_NOSIGHANDLER, but officially gpioCfgInternals() is deprecated and one should use gpioCfgSetInternals(). For all I can see in the code gpioCfgInternals() will only handle to distinct settings.

But all in all: There is some means of escape when the signal handling is bothering someone, so as far as I'm concerned, we can close this issue.

For a daemonized version it makes sense. Signals sent to the using program will never get to the daemon. For the library version one could use PI_CFG_NOSIGHANDLER.

@guymcswain
Copy link
Collaborator

I'll try to remember to update the doc and remove deprecated APIs for the next release.

@guymcswain guymcswain reopened this May 2, 2020
@frank1119
Copy link
Author

frank1119 commented May 2, 2020

That would be a good thing to do. Maybe some clarification for non-daemon users also?
Thank you.

By the way, I can confirm next code works:

int cfg = gpioCfgGetInternals();
cfg |= PI_CFG_NOSIGHANDLER;
gpioCfgSetInternals(cfg);
int status = gpioInitialise();

As you reopened this, I think you close this one?

@guymcswain
Copy link
Collaborator

guymcswain commented May 2, 2020

@frank1119 , Can you please test the latest commit on the repo's develop branch. It contains a potential 'fix' for your issue.

wget https://github.com/joan2937/pigpio/archive/develop.zip
unzip develop.zip
cd pigpio-develop
make
sudo make install

Update: Ignore this for now, error compiling. Sorry.

@guymcswain
Copy link
Collaborator

guymcswain commented May 2, 2020

Ok, the latest commit on the develop branch compiles and passes tests. I just don't have a test case written yet to see if it addresses concerns as you were seeing in your original description (prior to disabling the signal handler). I would be grateful if you could run this latest code to see if it resolves your issue. Thanks.

Note, the patch under test addresses issue #220. Now that I re-read your description they are probably not related.

@frank1119
Copy link
Author

I think you mix up issue #220 with this one, although I grant you that the underlying issue is rather alike.

Still, I've tested your commit https://codeload.github.com/joan2937/pigpio/zip/develop. That didn't compile, but to check whether there was a change in the behavior, I fixed the _exit() errors myself. But after that, the behavior for issue #341 didn't change (not completely unexpected).

@guymcswain
Copy link
Collaborator

Thanks, I think I need some sleep.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants