how to validate sigprocmask is working - linux

I am using sigprocmask to block signal and getting my process killed.
It works but is there a way to validate that say using /proc/<pid>/status
If I remove sigprocmask statements below the code does not work but I do not see any difference in /proc/<pid>/status with resepct to SigIgn,SigCgt,SigPnd ,Sig*
my $sigset_old = POSIX::SigSet->new;
my $sigset = POSIX::SigSet->new;
$sigset->emptyset();
$sigset->addset(&POSIX::SIGPOLL);
POSIX::sigprocmask(SIG_BLOCK,$sigset,$old_sigset);
while(1)
{
POSIX::RT::Signal::sigwait($sigset);
POSIX::sigprocmask(SIG_UNBLOCK,$old_sigset)
<some code>
...
...
}

Instead of:
POSIX::sigprocmask(SIG_UNBLOCK,$old_sigset)
do:
POSIX::sigprocmask(SIG_SETMASK,$old_sigset)
The old signal mask does not contain your POLL signal, so it is not unblocked in the second call. What you want is either to set the old signal mask like shown or to unblock your signal with
POSIX::sigprocmask(SIG_UNBLOCK,$sigset)
This is incorrectly documented in many places in the internet e.g. https://www.oreilly.com/library/view/perl-cookbook/1565922433/ch16s21.html
Seems like often, one copies from the other.

Related

Checking if a node has a connected signal with "is_connected" gives errors if there are no signals connected

In my project I dynamically (through the code) create LineEdits with fields the user can change in a popup WindowDialogue. In the similar manner I connect each LineEdit with a signal (text_entered) to a function which saves the changes made.
So, I have a simple function, which manages the WindowDialogue closing, i.e. deletes all children:
for child in parent.get_children():
if child.is_connected("text_entered", self, "_function_name"):
child.disconnect("text_entered", self, "_function_name")
child.queue_free()
As you can see I specifically make a check if a child has connections to remove before deleting the child node from the memory. As it is, the code works correctly. However, every time the check goes through the nodes (in my cases Labels) that do not have a signal connected, I get this error in the debugger:
is_connected: Nonexistent signal: text_entered.
That is a logical statement from the engine I cannot argue with. My question is: is there a way to make my check go through without this error?
This code should not show any errors even if nothing is connected to the signal. Probably parent has some child that really doesn't have the text_entered signal.
You can check whether a node (or other object) has the given signal with has_signal:
for child in parent.get_children():
if child.has_signal("text_entered") and child.is_connected("text_entered", self, "_function_name"):
child.disconnect("text_entered", self, "_function_name")
child.queue_free()
However, there's usually no need. Signals are disconnected automatically when the node is freed.
(When using queue_free, the node is freed at the end of the frame, not immediately, so there are edge cases where something like this is needed. But I don't think this is one of those cases.)
You could also check the type of the Node. For example:
for child in parent.get_children():
if not child is LineEdit:
continue
# rest of the code
Or if you are like me you prefer this:
for child in parent.get_children():
var line_edit := child as LineEdit
if not is_instance_valid(line_edit):
continue
# rest of the code

when use gpio_set_value, i can't get gpio state with gpio_get_value later

I'm learning how to setup key-interrupt with generic gpio. But there is problem that i can't understand what's wrong with my code.
gpio_is_valid(mygpio);
gpio_request(mygpio);
gpio_direction_output(……);
……
It's simple setting with the gpio-pin. Then I register an interrupt handler.In interrupt handler, I use the tasklet.
BUT! Strange thing happened! As follow:
gpio_set_value(mygpio, 1);
considered about that the hardware need time to run and set, so even I insert mdelay(100) here. After that invoke gpio_get_value(mygpio), the return is 0, zero!!!
At last, I disabled all interrupt and do above again.But nothing has changed. What's wrong happened??

RobotC: Multithreading in TeleOp (controlling mode)

I am making a program for a robot in a competition, and need to multithread.
When I make a second task (task two()) and try to start (startTask) it with a button press from a controller, it just executes the first statement of the task and only as long as the button is pressed, instead of the whole block. I've tried many things including putting a loop in the second task also, using a function instead of a task and sleeping for 200 milliseconds before, and after the startTask(two); function, but the same thing happens every time.
I can't post my program because I don't want other people to steal it, sorry.
What edits will make it run the whole block?
Any help would be appreciated.
Since this is Controller Mode, I'm assuming that you are setting the motors to stop when the corresponding button is not pressed.
if([...])
[...]
else
{
setMotorSpeed(motor10, 0);
}
This is the cause for the stopping of the motors when you release. All of the other methods that you tried had nothing to do with this, so they shouldn't have worked.
You need to put something like this:
int Motor10Speed;
[...]
if([...])
[...]
else
{
setMotorSpeed(motor10, Motor10Speed);
}
This will control an individual motor. Repeat this for all other motors being used.
After that is done, make the function look something like this:
task mini_function();
task main()
{
[...]
}
task mini_function()
{
Motor10Speed = 50;
sleep(1000);
Motor10Speed = 0;
}
Expand the above program so it matches your current function, while using the MotorSpeed variables as setMotorSpeed variables.
This should make you able to drive and run a function at the same time without them interrupting each other.

MFC dialog frozen

I need help how to unfreeze my dialog box. I'm using MFC and I have an infinite loop I want to execute when a button is pressed. However, the dialog box freezes when the infinite loop starts. Now I looked at this thread where someone was having a similar problem.
Unfortunately I tried multithreading but I found out that It can't work for me because I'm using an api that uses OLE automation and I'm getting an unhandled memory exception. I think this is because program uses the serial port and i read somewhere you can only use the handle to the serial port in one thread.
My program is simply to see if someone has dialed in to my modem and wait for them to send me a file, then hangup. Here is my loop.
while(1)
{
//get rid of input buffer
ts->_this->m_pHAScript->haReleaseRemoteInput();
ts-> _this->textBox->SetWindowTextA("thread Commence");
//wait for connected
if(success = ts->_this->m_pHAScript->haWaitForString("CONNECT",timeout))
{
//getFile
if(success = ts->_this->m_pHAScript->haWaitForXfer(5000))
{
//hangup
ts->_this->haTypeText("+++ath\r");
}
}
}
Is there a way to unfreeze the dialog box?
Add this code inside while loop:
MSG msg;
while(PeekMessage(&msg, GetSafeHwnd(), 0, 0, PM_REMOVE))
{
DispatchMessage(&msg);
}
The GUI in Windows relies on a message loop - somewhere in your code, either explicitly or hidden in a framework, there's a loop that checks for a message in a queue and processes it. If anything blocks the code from returning to that loop, the GUI gets frozen.
There are a few ways around this. One was given by David Brabant, essentially duplicating the loop. Another is to start a new "worker" thread that runs the blocking operation independently. If your message loop has a function that it calls when it is idle, i.e. no more messages are in the queue, you can do some processing there; that's not possible in your example however.

PostMessage returns "invalid window handle" in thread

Background: I am using OmniThreadLibrary to load batch mode ADO stored procedures in the background. I am doing some slightly dodgy stuff by swapping the connection after opening the SP but that seems to be quite reliable. I'm using PostMessage to send messages back to the calling form and that works in my test applications. Primoz' comms channels work for me, I'm using those for inter-thread comms but for our main application I'm trying to avoid that dependency by using standard PostMessage calls as we do elsewhere in the app.
Problem: Unfortunately when I put this into our main application the PostMessage calls in the thread start failing with 1400:invalid window handle.
I have liberally added extra PostMessage calls and logging code to try to locate the problem, but I'm out of ideas now. The code is boilerplate:
const WM_PW_ADLQUEUEEMPTY = WM_USER + 11;
...
if PostMessage (OwnerHandle, WM_PW_ADLPROGRESS, QueueID, 10) then
pwDebugLog ('TADLQueue.Run WM_PW_ADLPROGRESS send to ' + IntToHex (OwnerHandle, 8) + ' (IsWindow '+BoolToStr(IsWindow(OwnerHandle),true)+') OK for Queue ' + IntToStr (QueueID))
else
pwDebugLog ('TADLQueue.Run WM_PW_ADLPROGRESS send to ' + IntToHex (OwnerHandle, 8) + ' (IsWindow '+BoolToStr(IsWindow(OwnerHandle),true)+') failed for Queue ' + IntToStr (QueueID));
But the log for a series of calls is not very revealing to me. note that the four hex digits after the time is the thread id from GetCurrentThreadID.
15:41:53.221 1614 TpwAsyncDataLoader.RunQueue WM_PW_ADLPROGRESS send to 00A5110C (IsWindow True) OK for Queue -6
15:41:53.265 13B4 TADLQueue.Run WM_PW_ADLPROGRESS send to 00A5110C (IsWindow True) OK for Queue -6
15:41:53.554 13B4 TADLQueueManager.WriteSysErrorMessageToDatabase Postmessage 00A5110C (IsWindow False) failed with 1400 Invalid window handle
Can anyone shed some light on this? I'm confused at how a window handle can become invalid while I'm looking at it, but that's what it looks like to me.
The one thing I can think of is that the form I'm showing here isn't processing messages and I'm seeing a "message queue full" failure rather than the IsWindow(handle) failure that it looks like. How can I test for that?
There are cases where a handle gets recreated, most notably when you change window flags. This might be what's happening in your application.
All I found so far about recreating windows handle is this post from Allen Bauer but I'm certain reading a more detailed one written by Peter Below. Unfortunatly I can't seem to find that one.
Finally, you need to be aware of cases
where your handle may need to get
recreated. This can happen if the
surrounding form or the parent
component's handle goes through a
recreate process. Up until more recent
releases of Windows, the only way to
change some window flags was to
destroy the handle and recreate with
new flags in the CreateWindowEx()
call. There are many components that
still do this. You know if you're in a
recreate situation by checking
(csRecreating in ControlState).
Edit
Not actually the posts from Peter I had in mind but it might give you some fresh ideas.
The form will not have a handle until
you show it the first time (unless
something in the form load sequence
request the handle) but the handle is
not destroyed when you hide the form
and unless you do something that
forces the form to recreate the
handle, e.g. change its border style
or border icons, or call RecreateWnd
yourself the handle will stay the
same.
It may not be desirable but it cannot
be avoided, at least not the way
Delphi drag&dock is currently
implemented. When you dock the dragged
form to another form it becomes a
control (with WS_CHILD window style)
and that means that its window handle
has to be destroyed and recreated with
the new style. And destroying the
window handle of a container control
automatically destroys the handles for
all child controls as well.
and
There is also the fact that the forms
window handle is destroyed and
recreated when you assign to its
Parent property. This also destroys
and recreates the handles for all
controls on the form.
I had a similar issue (but in VC++2010), and I did not find the solution on any forum, so I post it here, hope this will help:
Issue:
Creating a thread,
Passing the HWnd handle
In the thread, PostMessage
throws a 1400 error (invalid handle), although the pointer was equal
with the handle as seen from UI thread (with GetSafeHWnd()).
Solution:
Do not pass the handle, but the parent CDialog(Ex) class
This class has a m_hWnd member that will do the job
Here is a (Cpp) example, sorry for the cast mess.
// In the worker thread
ThreadParam *threadParam = (ThreadParam*)param
// This is ugly because my pointer is a void *, to avoid one more forward declaration
CCoreGenDlg *dlg = static_cast<CCoreGenDlg *>(threadParam->ptr);
// Post
bool b = PostMessage(dlg->m_hWnd ,1221,0,(LPARAM)message);
Cheers'

Resources