kqueue()

sparc

Member
Halloechen,
ich beschaeftige mich gerade mit file-events und kqueue., dabei bin ich auf ein verhalten von kqueue gestossen, was ich so in keiner doku finde.
Also ich erzeuge ganz normal ein kevent mit
Code:
EV_SET( &listen, fh, EVFILT_VNODE, EV_ADD,
		NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB, 0, fi);
und registriere die struc mit
Code:
kevent(kq, &listen, 1, NULL, 0, NULL)
Den letzten parameter setze ich mit NULL, da ich einen blockierenden poll von kqueue haben moechte(laut man pages etc).
das funktioniert auch bis zum ersten event, dann wird der block aufgehoben und die events rauschen so durch. Laut doku sollte dies eigentlich nicht so sein, vorallem weil durch EV_ADD die events in kqueue registriert bleiben, im gegensatz zu EV_ONESHOT, wo jeder event nach benachrichtigung geloescht wird.

ich hoffe jemand hat einen tip oder kann das verhalten bestaetigen.

Gruss
Matthias
 
So wie gezeigt wird kevent() sicher nicht blockieren, da nevents 0 ist:
kqueue(2) said:
When nevents is zero, kevent() will return immediately even if there is a timeout specified unlike select(2).
Ohne eine Ereignisliste kannst du keine Ereignisse abwarten.
Was bedeutet "die events rauschen so durch"? Wenn Ereignisse anstehen, dann kehrt kevent() (bei gegebeneer Ereignisliste) logischerweise sofort zurück, denn es gibt etwas zu berichten.
Zeig etwas mehr Kontext als diese mageren zwei Zeilen.
 
Es wäre ja auch zu schön, wenn es eine Fassung der read() und write() Systemcalls sowie kevent()/kqueue() gäbe mit der man auf mehrere Events warten könnte ähnlich wie Interrupt migation in NICs.
 
zum verstaendnis noch was code:

Code:
	for(;;)
	{
                //warten auf den event
                //blockierender poll
		nev = kevent(kq, NULL, 0, &events, 1, NULL);
    	        if(nev == -1)
			perror("kevent");
		else if(nev > 0)
		{
			//printf("<event gefunden>\n");
			if( events.filter == EVFILT_VNODE)
			{
				if(events.fflags & NOTE_EXTEND || events.fflags & NOTE_WRITE)
				{
                                        //datei geaendert
                                        //darauf reagieren

				}
				if (events.fflags & NOTE_DELETE)
				{
                                      //geloescht....
				      printf("<File deleted>\n");
                                      
	    	                }
			}
		}
	}

der aufruf der funktion kqueue im anfangsthread diente zum registrieren des event.
wenn ich die man pages richtig verstehe, ist jeder poll blockierend, dh der aufruf blockiert die schleife. fuer den ersten event stimmt das auch. nach dem ersten event ist der aufruf nicht mehr blockierend, sondern die schleife laeuft durch und die events werden danach durch ifs gemeldet - klar.
so verstehe die man pages und die beispiele die ich gefunden habe nicht, zumal laut doku die events registriert bleiben und nicht geloescht werden.
ich benoetige aber die blockierende funktion...

gruss
Matthias
 
Solved

nach weiteren experimenten und nochmaligen lesen der mp habe ich folgendes heausgefunden:
events werden mit einem status registriert und kqueue hinzugefuegt. mit dem feuern eines events wird status geswitched, der event bleibt zwar in der queue wird aber durch den neuen status nicht mehr mitgezaehlt und der blocking poll wird aufgehoben; er wird auch nicht noch mals getriggert.
so jetzt kommen die flags ins spiel: mit EV_CLEAR wird nach dem feuern des events der status wieder zurueckgesetzt, so das der event wieder aktivert wird und damit wieder gefeuert werden kann.
dass die events interne statis haben war aus der mp nicht so direkt herauszulesen, erst bei durchsicht der flags bekam das ganze erst einen sinn.

gruss
Matthias

PS: das verhalten der kqueue ist trotzdem noch nicht so ganz klar: es gibt wohl nur einen status, der auch fuer mehrere events gilt, dh. ein gefeuerter event hebt den ganzen block poll fuer alle events auf.
 
Back
Top