Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Mar 2015 23:15:41 +0100
From:      Jilles Tjoelker <jilles@stack.nl>
To:        Ivan Radovanovic <radovanovic@gmail.com>
Cc:        freebsd-hackers@FreeBSD.org
Subject:   Re: kevent behavior
Message-ID:  <20150324221541.GA67584@stack.nl>
In-Reply-To: <550A6DA2.1070004@gmail.com>
References:  <550A6DA2.1070004@gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Mar 19, 2015 at 07:33:06AM +0100, Ivan Radovanovic wrote:
> Is there defined (and guaranteed) behavior of kevent if kqueue FD is 
> being closed while blocking kevent call is in progress?

> Possible scenario would be like this:

> Thread 1:
> ...
> kfd = kqueue();
> ...
> // create second thread afterwords
> // and do blocking wait for events
> result = kevent(kfd, changelist, nchanges, eventlist, nevents, NULL);
> if (result == -1)
> 	// check if there was request to stop listening for events

> Thread 2:
> // do something
> // then close kqueue's fd
> close(kfd);

> I am asking this because file watcher implementation for mono is 
> implemented that way (which I find nicer than using timeout), but this 
> is apparently based on expected kevent behavior under Darwin, and I 
> can't find any mention that in FreeBSD kevent is going to behave the 
> same way (at least not on kqueue(2) manual page)

This method is inherently unsafe, since you cannot be sure thread 1 has
started blocking in kevent() when you close() in thread 2. If not, there
might be a thread 3 creating a kqueue between thread 2's close and
thread 1's kevent, and thread 1 will manipulate the new kqueue.

Fortunately, EVFILT_USER provides an easy way to wake up a thread
blocked in kevent().

If kevent() was implemented as a cancellation point, pthread_cancel()
would be another option, but it is not.

-- 
Jilles Tjoelker



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20150324221541.GA67584>