|  | @@ -0,0 +1,127 @@
 | 
		
	
		
			
			|  | 1 | +#ifndef _IPXE_POOL_H
 | 
		
	
		
			
			|  | 2 | +#define _IPXE_POOL_H
 | 
		
	
		
			
			|  | 3 | +
 | 
		
	
		
			
			|  | 4 | +/** @file
 | 
		
	
		
			
			|  | 5 | + *
 | 
		
	
		
			
			|  | 6 | + * Pooled connections
 | 
		
	
		
			
			|  | 7 | + *
 | 
		
	
		
			
			|  | 8 | + */
 | 
		
	
		
			
			|  | 9 | +
 | 
		
	
		
			
			|  | 10 | +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
		
	
		
			
			|  | 11 | +
 | 
		
	
		
			
			|  | 12 | +#include <ipxe/interface.h>
 | 
		
	
		
			
			|  | 13 | +#include <ipxe/list.h>
 | 
		
	
		
			
			|  | 14 | +#include <ipxe/retry.h>
 | 
		
	
		
			
			|  | 15 | +
 | 
		
	
		
			
			|  | 16 | +/** A pooled connection */
 | 
		
	
		
			
			|  | 17 | +struct pooled_connection {
 | 
		
	
		
			
			|  | 18 | +	/** List of pooled connections
 | 
		
	
		
			
			|  | 19 | +	 *
 | 
		
	
		
			
			|  | 20 | +	 * Note that each connecton in the pool has a running expiry
 | 
		
	
		
			
			|  | 21 | +	 * timer which holds a reference to the connection.  We
 | 
		
	
		
			
			|  | 22 | +	 * therefore do not require the connection pool list to hold a
 | 
		
	
		
			
			|  | 23 | +	 * reference for each pooled connection.
 | 
		
	
		
			
			|  | 24 | +	 */
 | 
		
	
		
			
			|  | 25 | +	struct list_head list;
 | 
		
	
		
			
			|  | 26 | +	/** Expiry timer */
 | 
		
	
		
			
			|  | 27 | +	struct retry_timer timer;
 | 
		
	
		
			
			|  | 28 | +	/** Close expired pooled connection
 | 
		
	
		
			
			|  | 29 | +	 *
 | 
		
	
		
			
			|  | 30 | +	 * @v pool		Pooled connection
 | 
		
	
		
			
			|  | 31 | +	 */
 | 
		
	
		
			
			|  | 32 | +	void ( * expired ) ( struct pooled_connection *pool );
 | 
		
	
		
			
			|  | 33 | +	/** Flags */
 | 
		
	
		
			
			|  | 34 | +	unsigned int flags;
 | 
		
	
		
			
			|  | 35 | +};
 | 
		
	
		
			
			|  | 36 | +
 | 
		
	
		
			
			|  | 37 | +/** Pooled connection flags */
 | 
		
	
		
			
			|  | 38 | +enum pooled_connection_flags {
 | 
		
	
		
			
			|  | 39 | +	/** Connection should be recycled after closing */
 | 
		
	
		
			
			|  | 40 | +	POOL_RECYCLABLE = 0x0001,
 | 
		
	
		
			
			|  | 41 | +	/** Connection has been recycled */
 | 
		
	
		
			
			|  | 42 | +	POOL_RECYCLED = 0x0002,
 | 
		
	
		
			
			|  | 43 | +	/** Connection is known to be alive */
 | 
		
	
		
			
			|  | 44 | +	POOL_ALIVE = 0x0004,
 | 
		
	
		
			
			|  | 45 | +};
 | 
		
	
		
			
			|  | 46 | +
 | 
		
	
		
			
			|  | 47 | +extern void pool_add ( struct pooled_connection *pool, struct list_head *list,
 | 
		
	
		
			
			|  | 48 | +		       unsigned long expiry );
 | 
		
	
		
			
			|  | 49 | +extern void pool_del ( struct pooled_connection *pool );
 | 
		
	
		
			
			|  | 50 | +extern void pool_expired ( struct retry_timer *timer, int over );
 | 
		
	
		
			
			|  | 51 | +
 | 
		
	
		
			
			|  | 52 | +/**
 | 
		
	
		
			
			|  | 53 | + * Initialise a pooled connection
 | 
		
	
		
			
			|  | 54 | + *
 | 
		
	
		
			
			|  | 55 | + * @v pool		Pooled connection
 | 
		
	
		
			
			|  | 56 | + * @v expired		Close expired pooled connection method
 | 
		
	
		
			
			|  | 57 | + * @v refcnt		Containing object reference counter
 | 
		
	
		
			
			|  | 58 | + */
 | 
		
	
		
			
			|  | 59 | +static inline __attribute__ (( always_inline )) void
 | 
		
	
		
			
			|  | 60 | +pool_init ( struct pooled_connection *pool,
 | 
		
	
		
			
			|  | 61 | +	    void ( * expired ) ( struct pooled_connection *pool ),
 | 
		
	
		
			
			|  | 62 | +	    struct refcnt *refcnt ) {
 | 
		
	
		
			
			|  | 63 | +
 | 
		
	
		
			
			|  | 64 | +	INIT_LIST_HEAD ( &pool->list );
 | 
		
	
		
			
			|  | 65 | +	timer_init ( &pool->timer, pool_expired, refcnt );
 | 
		
	
		
			
			|  | 66 | +	pool->expired = expired;
 | 
		
	
		
			
			|  | 67 | +}
 | 
		
	
		
			
			|  | 68 | +
 | 
		
	
		
			
			|  | 69 | +/**
 | 
		
	
		
			
			|  | 70 | + * Mark pooled connection as recyclable
 | 
		
	
		
			
			|  | 71 | + *
 | 
		
	
		
			
			|  | 72 | + * @v pool		Pooled connection
 | 
		
	
		
			
			|  | 73 | + */
 | 
		
	
		
			
			|  | 74 | +static inline __attribute__ (( always_inline )) void
 | 
		
	
		
			
			|  | 75 | +pool_recyclable ( struct pooled_connection *pool ) {
 | 
		
	
		
			
			|  | 76 | +
 | 
		
	
		
			
			|  | 77 | +	pool->flags |= POOL_RECYCLABLE;
 | 
		
	
		
			
			|  | 78 | +}
 | 
		
	
		
			
			|  | 79 | +
 | 
		
	
		
			
			|  | 80 | +/**
 | 
		
	
		
			
			|  | 81 | + * Mark pooled connection as alive
 | 
		
	
		
			
			|  | 82 | + *
 | 
		
	
		
			
			|  | 83 | + * @v pool		Pooled connection
 | 
		
	
		
			
			|  | 84 | + */
 | 
		
	
		
			
			|  | 85 | +static inline __attribute__ (( always_inline )) void
 | 
		
	
		
			
			|  | 86 | +pool_alive ( struct pooled_connection *pool ) {
 | 
		
	
		
			
			|  | 87 | +
 | 
		
	
		
			
			|  | 88 | +	pool->flags |= POOL_ALIVE;
 | 
		
	
		
			
			|  | 89 | +}
 | 
		
	
		
			
			|  | 90 | +
 | 
		
	
		
			
			|  | 91 | +/**
 | 
		
	
		
			
			|  | 92 | + * Check if pooled connection is recyclable
 | 
		
	
		
			
			|  | 93 | + *
 | 
		
	
		
			
			|  | 94 | + * @v pool		Pooled connection
 | 
		
	
		
			
			|  | 95 | + * @ret recyclable	Pooled connection is recyclable
 | 
		
	
		
			
			|  | 96 | + */
 | 
		
	
		
			
			|  | 97 | +static inline __attribute__ (( always_inline )) int
 | 
		
	
		
			
			|  | 98 | +pool_is_recyclable ( struct pooled_connection *pool ) {
 | 
		
	
		
			
			|  | 99 | +
 | 
		
	
		
			
			|  | 100 | +	return ( pool->flags & POOL_RECYCLABLE );
 | 
		
	
		
			
			|  | 101 | +}
 | 
		
	
		
			
			|  | 102 | +
 | 
		
	
		
			
			|  | 103 | +/**
 | 
		
	
		
			
			|  | 104 | + * Check if pooled connection is reopenable
 | 
		
	
		
			
			|  | 105 | + *
 | 
		
	
		
			
			|  | 106 | + * @v pool		Pooled connection
 | 
		
	
		
			
			|  | 107 | + * @ret reopenable	Pooled connection is reopenable
 | 
		
	
		
			
			|  | 108 | + */
 | 
		
	
		
			
			|  | 109 | +static inline __attribute__ (( always_inline )) int
 | 
		
	
		
			
			|  | 110 | +pool_is_reopenable ( struct pooled_connection *pool ) {
 | 
		
	
		
			
			|  | 111 | +
 | 
		
	
		
			
			|  | 112 | +	/* A connection is reopenable if it has been recycled but is
 | 
		
	
		
			
			|  | 113 | +	 * not yet known to be alive.
 | 
		
	
		
			
			|  | 114 | +	 */
 | 
		
	
		
			
			|  | 115 | +	return ( ( pool->flags & POOL_RECYCLED ) &
 | 
		
	
		
			
			|  | 116 | +		 ( ! ( pool->flags & POOL_ALIVE ) ) );
 | 
		
	
		
			
			|  | 117 | +}
 | 
		
	
		
			
			|  | 118 | +
 | 
		
	
		
			
			|  | 119 | +extern void pool_recycle ( struct interface *intf );
 | 
		
	
		
			
			|  | 120 | +#define pool_recycle_TYPE( object_type ) \
 | 
		
	
		
			
			|  | 121 | +	typeof ( void ( object_type ) )
 | 
		
	
		
			
			|  | 122 | +
 | 
		
	
		
			
			|  | 123 | +extern void pool_reopen ( struct interface *intf );
 | 
		
	
		
			
			|  | 124 | +#define pool_reopen_TYPE( object_type ) \
 | 
		
	
		
			
			|  | 125 | +	typeof ( void ( object_type ) )
 | 
		
	
		
			
			|  | 126 | +
 | 
		
	
		
			
			|  | 127 | +#endif /* _IPXE_POOL_H */
 |