Example #1
0
/**
 * If the Event is pending, this function clears its pending status and
 * returns its revents bitset (as if its callback was invoked). If the watcher
 * isn't pending it returns 0.
 * 
 * @return int  revents bitset if pending, 0 if not (or not associated with EventLoop)
 */
PHP_METHOD(Event, clearPending)
{
	int revents = 0;
	event_object *event = (event_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
	
	if(event->loop_obj)
	{
		revents = event_clear_pending(event->loop_obj, event);
		
		/* Inactive event, meaning it is no longer part of the event loop
		   and must be dtor:ed (most probably a fed event which has never
		   become active because ev_TYPE_start has not been called) */
		if( ! event_is_active(event))
		{
			EVENT_LOOP_REF_DEL(event);
		}
		
		RETURN_LONG(revents);
	}
	
	RETURN_LONG(0);
}
Example #2
0
PHP_METHOD(PeriodicEvent, again)
{
	/* TODO: Optional EventLoop parameter? */
	event_object *event_obj = (event_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
	
	if(event_has_loop(event_obj))
	{
		event_periodic_again(event_obj);
		
		if( ! event_is_active(event_obj) && ! event_is_pending(event_obj))
		{
			/* No longer referenced by libev, so remove GC protection */
			IF_DEBUG(libev_printf("ev_periodic_again() stopped non-repeating timer\n"));
			EVENT_LOOP_REF_DEL(event_obj);
		}
		
		RETURN_BOOL(1);
	}
	
	/* TODO: Throw exception */
	RETURN_BOOL(0);
}
Example #3
0
/**
 * Feeds the given event set into the event loop, as if the specified event
 * had happened for the specified watcher.
 * 
 * The watcher will be GC protected until it has fired or clearPending is called
 * on it (unless you feed it again in the callback or add() it to an event loop
 * it won't accidentally be freed).
 * 
 * NOTE: As of libev 4.0.4; If you feed an event in the callback of a fed event,
 *       the newly fed event will be invoked before any other events (except other
 *       fed events). So do NOT create loops by re-feeding an event into the EventLoop
 *       as that loop will block just as much as a normal loop.
 * 
 * TODO: Add note about AsyncEvent when AsyncEvent is implemented
 * 
 * @param  Event
 * @return boolean  false if either the EventLoop or Event has not been initialized
 */
PHP_METHOD(EventLoop, feedEvent)
{
	int revents = 0;
	zval *event_obj;
	event_object *event;
	event_loop_object *loop_obj = (event_loop_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
	
	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|l", &event_obj, event_ce, &revents) != SUCCESS) {
		return;
	}
	
	event = (event_object *)zend_object_store_get_object(event_obj TSRMLS_CC);
	
	assert(loop_obj->loop);
	
	/* Only allow Events which are associated with this EventLoop
	   or those which are not associated with any EventLoop yet */
	if(loop_obj->loop &&
		( ! event_has_loop(event) || event_in_loop(loop_obj, event)))
	{
		IF_DEBUG(libev_printf("Feeding event with pending %d and active %d...",
			event_is_pending(event), event_is_active(event)));
		
		/* The event might already have a loop, no need to increase refcount */
		if( ! event_has_loop(event))
		{
			EVENT_LOOP_REF_ADD(event, loop_obj);
		}
		
		event_feed_event(loop_obj, event, revents);
		
		IF_DEBUG(php_printf(" done\n"));
		
		RETURN_BOOL(1);
	}
	
	RETURN_BOOL(0);
}
Example #4
0
/**
 * Removes the event from the event loop, will skip all pending events on it too.
 * 
 * @param  Event
 * @return boolean  False if the Event is not associated with this EventLoop,
 *                  can also be false if there is an error
 */
PHP_METHOD(EventLoop, remove)
{
	zval *event_obj;
	event_object *event;
	event_loop_object *loop_obj = (event_loop_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
	
	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &event_obj, event_ce) != SUCCESS) {
		return;
	}
	
	event = (event_object *)zend_object_store_get_object(event_obj TSRMLS_CC);
	
	assert(loop_obj->loop);
	
	if(loop_obj->loop && event_is_active(event))
	{
		assert(event->loop_obj);
		
		/* Check that the event is associated with us */
		if( ! event_in_loop(loop_obj, event))
		{
			IF_DEBUG(libev_printf("Event is not in this EventLoop\n"));
			
			RETURN_BOOL(0);
		}
		
		EVENT_STOP(event);
		
		/* Remove GC protection, no longer active or pending */
		EVENT_LOOP_REF_DEL(event);
		
		RETURN_BOOL(1);
	}
	
	RETURN_BOOL(0);
}
Example #5
0
/**
 * Returns true if the event is active, ie. associated with an event loop.
 * 
 * @return boolean
 * @return null  If object has not been initialized
 */
PHP_METHOD(Event, isActive)
{
	event_object *obj = (event_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
	
	RETURN_BOOL(event_is_active(obj));
}
Example #6
0
/**
 * Adds the event to the event loop.
 * 
 * This method will increase the refcount on the supplied Event, protecting it
 * from garbage collection. Refcount will be decreased on remove or if the
 * EventLoop object is GCd.
 * 
 * @param  Event
 * @return boolean
 */
PHP_METHOD(EventLoop, add)
{
	zval *zevent;
	event_object *event;
	event_loop_object *loop_obj = (event_loop_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
	
	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zevent, event_ce) != SUCCESS) {
		return;
	}
	
	event = (event_object *)zend_object_store_get_object(zevent TSRMLS_CC);
	
	assert(loop_obj->loop);
	
	/* Check so the event is not associated with any EventLoop, also needs to check
	   for active, no need to perform logic if it already is started */
	if(loop_obj->loop && ! event_is_active(event))
	{
		if(event_has_loop(event))
		{
			if( ! event_in_loop(loop_obj, event))
			{
				/* Attempting to add a fed event to this EventLoop which
				   has been fed to another loop */
				IF_DEBUG(libev_printf("Attempting to add() an event already associated with another EventLoop\n"));
				RETURN_BOOL(0);
			}
		}
		
		EVENT_WATCHER_ACTION(event, loop_obj, start, io)
		else EVENT_WATCHER_ACTION(event, loop_obj, start, timer)
		else EVENT_WATCHER_ACTION(event, loop_obj, start, periodic)
		else EVENT_WATCHER_ACTION(event, loop_obj, start, signal)
		else if(instance_of_class(event->std.ce, child_event_ce))
		{
			/* Special logic, ev_child can only be attached to the default loop */
			if( ! ev_is_default_loop(loop_obj->loop))
			{
				/* TODO: libev-specific exception class here */
				zend_throw_exception(NULL, "libev\\ChildEvent can only be added to the default event-loop", 1 TSRMLS_DC);
				
				return;
			}
			
			ev_child_start(loop_obj->loop, (ev_child *)event->watcher);
			IF_DEBUG(libev_printf("Calling ev_child_start\n"));
		}
		else EVENT_WATCHER_ACTION(event, loop_obj, start, stat)
		else EVENT_WATCHER_ACTION(event, loop_obj, start, idle)
		else EVENT_WATCHER_ACTION(event, loop_obj, start, async)
		else EVENT_WATCHER_ACTION(event, loop_obj, start, cleanup)
		
		if( ! event_has_loop(event))
		{
			/* GC protection */
			EVENT_LOOP_REF_ADD(event, loop_obj);
		}
		
		RETURN_BOOL(1);
	}
	
	RETURN_BOOL(0);
}