summaryrefslogtreecommitdiffstats
path: root/qemu/roms/ipxe/src/include/ipxe/pool.h
blob: 27066e9b38c099d73c91311f2f64bc1b5c53cb30 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#ifndef _IPXE_POOL_H
#define _IPXE_POOL_H

/** @file
 *
 * Pooled connections
 *
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <ipxe/interface.h>
#include <ipxe/list.h>
#include <ipxe/retry.h>

/** A pooled connection */
struct pooled_connection {
	/** List of pooled connections
	 *
	 * Note that each connecton in the pool has a running expiry
	 * timer which holds a reference to the connection.  We
	 * therefore do not require the connection pool list to hold a
	 * reference for each pooled connection.
	 */
	struct list_head list;
	/** Expiry timer */
	struct retry_timer timer;
	/** Close expired pooled connection
	 *
	 * @v pool		Pooled connection
	 */
	void ( * expired ) ( struct pooled_connection *pool );
	/** Flags */
	unsigned int flags;
};

/** Pooled connection flags */
enum pooled_connection_flags {
	/** Connection should be recycled after closing */
	POOL_RECYCLABLE = 0x0001,
	/** Connection has been recycled */
	POOL_RECYCLED = 0x0002,
	/** Connection is known to be alive */
	POOL_ALIVE = 0x0004,
};

extern void pool_add ( struct pooled_connection *pool, struct list_head *list,
		       unsigned long expiry );
extern void pool_del ( struct pooled_connection *pool );
extern void pool_expired ( struct retry_timer *timer, int over );

/**
 * Initialise a pooled connection
 *
 * @v pool		Pooled connection
 * @v expired		Close expired pooled connection method
 * @v refcnt		Containing object reference counter
 */
static inline __attribute__ (( always_inline )) void
pool_init ( struct pooled_connection *pool,
	    void ( * expired ) ( struct pooled_connection *pool ),
	    struct refcnt *refcnt ) {

	INIT_LIST_HEAD ( &pool->list );
	timer_init ( &pool->timer, pool_expired, refcnt );
	pool->expired = expired;
}

/**
 * Mark pooled connection as recyclable
 *
 * @v pool		Pooled connection
 */
static inline __attribute__ (( always_inline )) void
pool_recyclable ( struct pooled_connection *pool ) {

	pool->flags |= POOL_RECYCLABLE;
}

/**
 * Mark pooled connection as alive
 *
 * @v pool		Pooled connection
 */
static inline __attribute__ (( always_inline )) void
pool_alive ( struct pooled_connection *pool ) {

	pool->flags |= POOL_ALIVE;
}

/**
 * Check if pooled connection is recyclable
 *
 * @v pool		Pooled connection
 * @ret recyclable	Pooled connection is recyclable
 */
static inline __attribute__ (( always_inline )) int
pool_is_recyclable ( struct pooled_connection *pool ) {

	return ( pool->flags & POOL_RECYCLABLE );
}

/**
 * Check if pooled connection is reopenable
 *
 * @v pool		Pooled connection
 * @ret reopenable	Pooled connection is reopenable
 */
static inline __attribute__ (( always_inline )) int
pool_is_reopenable ( struct pooled_connection *pool ) {

	/* A connection is reopenable if it has been recycled but is
	 * not yet known to be alive.
	 */
	return ( ( pool->flags & POOL_RECYCLED ) &
		 ( ! ( pool->flags & POOL_ALIVE ) ) );
}

extern void pool_recycle ( struct interface *intf );
#define pool_recycle_TYPE( object_type ) \
	typeof ( void ( object_type ) )

extern void pool_reopen ( struct interface *intf );
#define pool_reopen_TYPE( object_type ) \
	typeof ( void ( object_type ) )

#endif /* _IPXE_POOL_H */