Bläddra i källkod

[iobuf] Add iob_disown() and use it where it simplifies code

There are many functions that take ownership of the I/O buffer they
are passed as a parameter.  The caller should not retain a pointer to
the I/O buffer.  Use iob_disown() to automatically nullify the
caller's pointer, e.g.:

    xfer_deliver_iob ( xfer, iob_disown ( iobuf ) );

This will ensure that iobuf is set to NULL for any code after the call
to xfer_deliver_iob().

iob_disown() is currently used only in places where it simplifies the
code, by avoiding an extra line explicitly setting the I/O buffer
pointer to NULL.  It should ideally be used with each call to any
function that takes ownership of an I/O buffer.  (The SSA
optimisations will ensure that use of iob_disown() gets optimised away
in cases where the caller makes no further use of the I/O buffer
pointer anyway.)

If gcc ever introduces an __attribute__((free)), indicating that use
of a function argument after a function call should generate a
warning, then we should use this to identify all applicable function
call sites, and add iob_disown() as necessary.
tags/v0.9.7
Michael Brown 15 år sedan
förälder
incheckning
dbe84c5aad

+ 1
- 2
src/arch/i386/drivers/net/undinet.c Visa fil

482
 					 undi_isr.Frame.offset, frag_len );
482
 					 undi_isr.Frame.offset, frag_len );
483
 			if ( iob_len ( iobuf ) == len ) {
483
 			if ( iob_len ( iobuf ) == len ) {
484
 				/* Whole packet received; deliver it */
484
 				/* Whole packet received; deliver it */
485
-				netdev_rx ( netdev, iobuf );
486
-				iobuf = NULL;
485
+				netdev_rx ( netdev, iob_disown ( iobuf ) );
487
 				/* Etherboot 5.4 fails to return all packets
486
 				/* Etherboot 5.4 fails to return all packets
488
 				 * under mild load; pretend it retriggered.
487
 				 * under mild load; pretend it retriggered.
489
 				 */
488
 				 */

+ 20
- 0
src/include/gpxe/iobuf.h Visa fil

199
 	iobuf->end = ( data + max_len );
199
 	iobuf->end = ( data + max_len );
200
 }
200
 }
201
 
201
 
202
+/**
203
+ * Disown an I/O buffer
204
+ *
205
+ * @v iobuf	I/O buffer
206
+ *
207
+ * There are many functions that take ownership of the I/O buffer they
208
+ * are passed as a parameter.  The caller should not retain a pointer
209
+ * to the I/O buffer.  Use iob_disown() to automatically nullify the
210
+ * caller's pointer, e.g.:
211
+ *
212
+ *     xfer_deliver_iob ( xfer, iob_disown ( iobuf ) );
213
+ *
214
+ * This will ensure that iobuf is set to NULL for any code after the
215
+ * call to xfer_deliver_iob().
216
+ */
217
+#define iob_disown( iobuf ) ( {				\
218
+	struct io_buffer *__iobuf = (iobuf);		\
219
+	(iobuf) = NULL;					\
220
+	__iobuf; } )
221
+
202
 extern struct io_buffer * __malloc alloc_iob ( size_t len );
222
 extern struct io_buffer * __malloc alloc_iob ( size_t len );
203
 extern void free_iob ( struct io_buffer *iobuf );
223
 extern void free_iob ( struct io_buffer *iobuf );
204
 extern void iob_pad ( struct io_buffer *iobuf, size_t min_len );
224
 extern void iob_pad ( struct io_buffer *iobuf, size_t min_len );

+ 1
- 2
src/interface/efi/efi_snp.c Visa fil

602
 	}
602
 	}
603
 
603
 
604
 	/* Transmit packet */
604
 	/* Transmit packet */
605
-	if ( ( rc = netdev_tx ( snpdev->netdev, iobuf ) ) != 0 ) {
605
+	if ( ( rc = netdev_tx ( snpdev->netdev, iob_disown ( iobuf ) ) ) != 0){
606
 		DBGC ( snpdev, "SNPDEV %p TX could not transmit: %s\n",
606
 		DBGC ( snpdev, "SNPDEV %p TX could not transmit: %s\n",
607
 		       snpdev, strerror ( rc ) );
607
 		       snpdev, strerror ( rc ) );
608
-		iobuf = NULL;
609
 		efirc = RC_TO_EFIRC ( rc );
608
 		efirc = RC_TO_EFIRC ( rc );
610
 		goto err_tx;
609
 		goto err_tx;
611
 	}
610
 	}

+ 2
- 2
src/net/arp.c Visa fil

265
 	memcpy ( arp_sender_ha ( arphdr ), netdev->ll_addr, arphdr->ar_hln );
265
 	memcpy ( arp_sender_ha ( arphdr ), netdev->ll_addr, arphdr->ar_hln );
266
 
266
 
267
 	/* Send reply */
267
 	/* Send reply */
268
-	net_tx ( iobuf, netdev, &arp_protocol, arp_target_ha (arphdr ) );
269
-	iobuf = NULL;
268
+	net_tx ( iob_disown ( iobuf ), netdev, &arp_protocol,
269
+		 arp_target_ha ( arphdr ) );
270
 
270
 
271
  done:
271
  done:
272
 	free_iob ( iobuf );
272
 	free_iob ( iobuf );

+ 1
- 2
src/net/tcp/http.c Visa fil

340
 			/* Once we're into the data phase, just fill
340
 			/* Once we're into the data phase, just fill
341
 			 * the data buffer
341
 			 * the data buffer
342
 			 */
342
 			 */
343
-			rc = http_rx_data ( http, iobuf );
344
-			iobuf = NULL;
343
+			rc = http_rx_data ( http, iob_disown ( iobuf ) );
345
 			goto done;
344
 			goto done;
346
 		case HTTP_RX_RESPONSE:
345
 		case HTTP_RX_RESPONSE:
347
 		case HTTP_RX_HEADER:
346
 		case HTTP_RX_HEADER:

+ 1
- 2
src/net/udp.c Visa fil

328
 	memset ( &meta, 0, sizeof ( meta ) );
328
 	memset ( &meta, 0, sizeof ( meta ) );
329
 	meta.src = ( struct sockaddr * ) st_src;
329
 	meta.src = ( struct sockaddr * ) st_src;
330
 	meta.dest = ( struct sockaddr * ) st_dest;
330
 	meta.dest = ( struct sockaddr * ) st_dest;
331
-	rc = xfer_deliver_iob_meta ( &udp->xfer, iobuf, &meta );
332
-	iobuf = NULL;
331
+	rc = xfer_deliver_iob_meta ( &udp->xfer, iob_disown ( iobuf ), &meta );
333
 
332
 
334
  done:
333
  done:
335
 	free_iob ( iobuf );
334
 	free_iob ( iobuf );

+ 2
- 3
src/net/udp/dhcp.c Visa fil

976
 
976
 
977
 	/* Transmit the packet */
977
 	/* Transmit the packet */
978
 	iob_put ( iobuf, dhcppkt.len );
978
 	iob_put ( iobuf, dhcppkt.len );
979
-	rc = xfer_deliver_iob_meta ( &dhcp->xfer, iobuf, &meta );
980
-	iobuf = NULL;
981
-	if ( rc != 0 ) {
979
+	if ( ( rc = xfer_deliver_iob_meta ( &dhcp->xfer, iob_disown ( iobuf ),
980
+					    &meta ) ) != 0 ) {
982
 		DBGC ( dhcp, "DHCP %p could not transmit UDP packet: %s\n",
981
 		DBGC ( dhcp, "DHCP %p could not transmit UDP packet: %s\n",
983
 		       dhcp, strerror ( rc ) );
982
 		       dhcp, strerror ( rc ) );
984
 		goto done;
983
 		goto done;

+ 3
- 5
src/net/udp/tftp.c Visa fil

763
 	memset ( &meta, 0, sizeof ( meta ) );
763
 	memset ( &meta, 0, sizeof ( meta ) );
764
 	meta.whence = SEEK_SET;
764
 	meta.whence = SEEK_SET;
765
 	meta.offset = offset;
765
 	meta.offset = offset;
766
-	rc = xfer_deliver_iob_meta ( &tftp->xfer, iobuf, &meta );
767
-	iobuf = NULL;
768
-	if ( rc != 0 ) {
766
+	if ( ( rc = xfer_deliver_iob_meta ( &tftp->xfer, iob_disown ( iobuf ),
767
+					    &meta ) ) != 0 ) {
769
 		DBGC ( tftp, "TFTP %p could not deliver data: %s\n",
768
 		DBGC ( tftp, "TFTP %p could not deliver data: %s\n",
770
 		       tftp, strerror ( rc ) );
769
 		       tftp, strerror ( rc ) );
771
 		goto done;
770
 		goto done;
887
 		rc = tftp_rx_oack ( tftp, iobuf->data, len );
886
 		rc = tftp_rx_oack ( tftp, iobuf->data, len );
888
 		break;
887
 		break;
889
 	case htons ( TFTP_DATA ):
888
 	case htons ( TFTP_DATA ):
890
-		rc = tftp_rx_data ( tftp, iobuf );
891
-		iobuf = NULL;
889
+		rc = tftp_rx_data ( tftp, iob_disown ( iobuf ) );
892
 		break;
890
 		break;
893
 	case htons ( TFTP_ERROR ):
891
 	case htons ( TFTP_ERROR ):
894
 		rc = tftp_rx_error ( tftp, iobuf->data, len );
892
 		rc = tftp_rx_error ( tftp, iobuf->data, len );

Laddar…
Avbryt
Spara