Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <23f3de92.ba55.17051fd5c6b.Coremail.zuotingyang@126.com>
Date: Mon, 17 Feb 2020 15:12:03 +0800 (CST)
From: zuotina  <zuotingyang@....com>
To: musl@...ts.openwall.com
Subject: Re:Re: [timer] timer_delete function async problem

The pseudo-code example program as follows. There are two processes A and B.
process A:
void timer_handler(union sigval arg)
{
pctx = (struct ctx *)arg.sival_ptr;
if (pctx == NULL)
return;
// Here may be scheduled to timer_release of thread B.
// When scheduled again, the pctx was illeagal, so panic.
lock(pctx->lock);
/* do something with pctx */
unlock(pctx->lock);
}
void create_timer_function()
{
struct sigevent sig;
sig.sigev_notify = SIGEV_THREAD;
sig.sigev_value.sival_ptr = pctx; 
sig.sigev_notify_function = timer_handler;
timer_create(CLOCK_REALTIME, &sig, &pctx->timerid);
}


process B:
void timer_release()
{
lock(pctx->lock);
timer_delete(pctx->timerid);
unlock(pctx->lock);
// here will do something...
free(pctx);
}


After the call to timer_delete is made but before the signal is sent, 
a new handler which is not already-running will be coming at uncertain time.
I've tried synchronization and mutual between 'timer_release' and 'timer_handler', 
neither can be resolved. 
How to solve the panic in the example, hope to give some suggestions.









At 2020-02-16 01:27:26, "Rich Felker" <dalias@...c.org> wrote:
>On Sat, Feb 15, 2020 at 06:54:23PM +0800, zuotina wrote:
>> Hi everrone
>> 
>> 
>> Problem:
>> When I created SIGEV_THREAD timer, then start it by timer_settime. like this
>> the notify callback in the helper thread 'start' will be run when timer expiration.
>> But when I delete the timer, the notify callback will be run all the same.
>> This is not what i want. In actual use,  I encountered a problem.
>> 
>> 
>> I found that the 'timer_delete' function returns immediately after called.
>> The timer may not perform the delete action.
>
>Logically the timer is deleted before the timer_delete function
>returns. If the handler thread is still running a handler at the time,
>that will necessarily continue intil it exits; the specification makes
>no provision for timer_delete doing anything to already-running
>handler threads. Since the operations are inherently unordered, it's
>possible that a new handler physically starts running after the call
>to timer_delete is made but before the signal is sent; as far as I can
>tell this is not observable by the application (since there is no
>ordering).
>
>> In addition, the SIGEV_SIGNAL timer can be deleted after called the function. 
>> So i think the function has different semantics for different types.
>
>But doing so does not stop the signal handler from running (and
>fundamentally couldn't). So I don't understand what your concern is.
>Is it just that the kernel timer resource still exists until the
>handler thread finishes? I don't think that's visible to the
>application except possibly in limiting the number of timers that can
>be created.
>
>> Is there a way to implement synchronously ?
>
>At some point I plan to drop use of kernel timer resources entirely
>for SIGEV_THREAD timers, since they can be implemented *more easily*,
>with fewer hacks (no SIGTIMER at all! we can get rid of this reserved
>RT signal) with just a loop performing clock_nanosleep. If/when this
>change is made, there will be no kernel timer resource involed at all,
>so if I understand what you're asking, I guess that would give the
>behavior you want. (?)
>
>If I'm not understanding what you're asking for, could you send a
>minimal testcase program demonstrating how you observe a behavior you
>consider wrong without the test invoking any UB?
>
>Rich

Content of type "text/html" skipped

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.