Browse Source

[pending] Add concept of "pending operations"

iPXE is fundamentally asynchronous in operation: some operations
continue in the background even after the foreground has continued to
a new task.  For example, the closing FIN/ACK exchanges of a TCP
connection will take place in the background after an HTTP download
has completed.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 years ago
parent
commit
021d7b21b7
3 changed files with 114 additions and 0 deletions
  1. 79
    0
      src/core/pending.c
  2. 1
    0
      src/include/ipxe/errfile.h
  3. 34
    0
      src/include/ipxe/pending.h

+ 79
- 0
src/core/pending.c View File

@@ -0,0 +1,79 @@
1
+/*
2
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+FILE_LICENCE ( GPL2_OR_LATER );
20
+
21
+#include <errno.h>
22
+#include <ipxe/process.h>
23
+#include <ipxe/timer.h>
24
+#include <ipxe/pending.h>
25
+
26
+/** @file
27
+ *
28
+ * Pending operations
29
+ *
30
+ */
31
+
32
+/** Total count of pending operations */
33
+static int pending_total;
34
+
35
+/**
36
+ * Mark an operation as pending
37
+ *
38
+ * @v pending		Pending operation
39
+ */
40
+void pending_get ( struct pending_operation *pending ) {
41
+
42
+	pending->count++;
43
+	pending_total++;
44
+	DBGC ( pending, "PENDING %p incremented to %d (total %d)\n",
45
+	       pending, pending->count, pending_total );
46
+}
47
+
48
+/**
49
+ * Mark an operation as no longer pending
50
+ *
51
+ * @v pending		Pending operation
52
+ */
53
+void pending_put ( struct pending_operation *pending ) {
54
+
55
+	if ( pending->count ) {
56
+		pending_total--;
57
+		pending->count--;
58
+		DBGC ( pending, "PENDING %p decremented to %d (total %d)\n",
59
+		       pending, pending->count, pending_total );
60
+	}
61
+}
62
+
63
+/**
64
+ * Wait for pending operations to complete
65
+ *
66
+ * @v timeout		Timeout period, in ticks (0=indefinite)
67
+ * @ret rc		Return status code
68
+ */
69
+int pending_wait ( unsigned long timeout ) {
70
+	unsigned long start = currticks();
71
+
72
+	do {
73
+		if ( pending_total == 0 )
74
+			return 0;
75
+		step();
76
+	} while ( ( timeout == 0 ) || ( ( currticks() - start ) < timeout ) );
77
+
78
+	return -ETIMEDOUT;
79
+}

+ 1
- 0
src/include/ipxe/errfile.h View File

@@ -62,6 +62,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
62 62
 #define ERRFILE_parseopt	       ( ERRFILE_CORE | 0x00160000 )
63 63
 #define ERRFILE_test		       ( ERRFILE_CORE | 0x00170000 )
64 64
 #define ERRFILE_xferbuf		       ( ERRFILE_CORE | 0x00180000 )
65
+#define ERRFILE_pending		       ( ERRFILE_CORE | 0x00190000 )
65 66
 
66 67
 #define ERRFILE_eisa		     ( ERRFILE_DRIVER | 0x00000000 )
67 68
 #define ERRFILE_isa		     ( ERRFILE_DRIVER | 0x00010000 )

+ 34
- 0
src/include/ipxe/pending.h View File

@@ -0,0 +1,34 @@
1
+#ifndef _IPXE_PENDING_H
2
+#define _IPXE_PENDING_H
3
+
4
+/** @file
5
+ *
6
+ * Pending operations
7
+ *
8
+ */
9
+
10
+FILE_LICENCE ( GPL2_OR_LATER );
11
+
12
+#include <ipxe/list.h>
13
+
14
+/** A pending operation */
15
+struct pending_operation {
16
+	/** Pending count */
17
+	unsigned int count;
18
+};
19
+
20
+/**
21
+ * Check if an operation is pending
22
+ *
23
+ * @v pending		Pending operation
24
+ * @v is_pending	Operation is pending
25
+ */
26
+static inline int is_pending ( struct pending_operation *pending ) {
27
+	return ( pending->count != 0 );
28
+}
29
+
30
+extern void pending_get ( struct pending_operation *pending );
31
+extern void pending_put ( struct pending_operation *pending );
32
+extern int pending_wait ( unsigned long timeout );
33
+
34
+#endif /* _IPXE_PENDING_H */

Loading…
Cancel
Save