From owner-freebsd-hackers@FreeBSD.ORG Wed Mar 25 14:38:04 2015 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id D8C40A80 for ; Wed, 25 Mar 2015 14:38:04 +0000 (UTC) Received: from mail-wi0-x22e.google.com (mail-wi0-x22e.google.com [IPv6:2a00:1450:400c:c05::22e]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 782FDD6C for ; Wed, 25 Mar 2015 14:38:04 +0000 (UTC) Received: by wixw10 with SMTP id w10so41679771wix.0 for ; Wed, 25 Mar 2015 07:38:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type:content-transfer-encoding; bh=Sd7HSvFU1FQkMrDhpPwSCVmKLTDGSY1xxHty7EQ205g=; b=r1deeQTZuuqRwScCwFx176cAH3xKy/q7zeqpuLl3Ap29V20T8nbshpnSIL/4isNupU Qqala19TPgXBdZ3Rmhe/18WDUXOqRKrQI0+5LK/jZFg7mSRRXTuX79ftWCFdtweDwqrd V75so8bAfaJGe+dkf8DSk2roWOdkxr5ze3LUeKH7Yqta0sGOklytFkX7q7ILkBD7BAvE oxHbyKuWdEfI6BQQ67JB2eTuNmr+71fvupIc5b4Niu0ztP7dlY6uNtD8ixAmZR8k18Dx HceC7d5JmbYcf7tWdqJGhQYVVFtF3UjrVg57AjpqKEbVzlvMb/hmFONEPuVOj/vxJ06u sG/A== X-Received: by 10.180.198.162 with SMTP id jd2mr37741979wic.21.1427294264933; Wed, 25 Mar 2015 07:37:44 -0700 (PDT) Received: from azdaja.softwarehood.com ([95.180.18.169]) by mx.google.com with ESMTPSA id ka1sm4043920wjc.2.2015.03.25.07.37.43 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 25 Mar 2015 07:37:43 -0700 (PDT) Message-ID: <5512C835.7040207@gmail.com> Date: Wed, 25 Mar 2015 15:37:41 +0100 From: Ivan Radovanovic User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 MIME-Version: 1.0 To: Jilles Tjoelker Subject: Re: kevent behavior References: <550A6DA2.1070004@gmail.com> <20150324221541.GA67584@stack.nl> In-Reply-To: <20150324221541.GA67584@stack.nl> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-hackers@FreeBSD.org X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 25 Mar 2015 14:38:05 -0000 On 03/24/2015 23:15, Jilles Tjoelker wrote: > 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. > It is not really created in the same way as I put there, I just wanted to illustrate that we have 2 threads and that one is blocked in kevent and the other one is trying to close its kqueue descriptor. I saw this EVFILT_USER thing, and it looked to me like it could be used to do much smarter unblocking of kevent but I believe manual page is relatively unclear there - what I do not understand is: * how you trigger this user event (I would say with kevent if corresponding structure's NOTE_TRIGGER flag is set, but that doesn't sound logical since in my understanding kevent is basically like select(2) (ie call which checks if something happened without triggering things = call which reports about status change in system without causing change itself)? * how does this work process-wise - is one ident restricted to process which created corresponding kqueue, or it is system wise (other process could trigger my kevent if same ident value is used)?