[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.
This commit is contained in:
Michael Brown
2009-02-01 18:02:28 +00:00
parent 0171098212
commit dbe84c5aad
8 changed files with 31 additions and 18 deletions

View File

@@ -265,8 +265,8 @@ static int arp_rx ( struct io_buffer *iobuf, struct net_device *netdev,
memcpy ( arp_sender_ha ( arphdr ), netdev->ll_addr, arphdr->ar_hln );
/* Send reply */
net_tx ( iobuf, netdev, &arp_protocol, arp_target_ha (arphdr ) );
iobuf = NULL;
net_tx ( iob_disown ( iobuf ), netdev, &arp_protocol,
arp_target_ha ( arphdr ) );
done:
free_iob ( iobuf );

View File

@@ -340,8 +340,7 @@ static int http_socket_deliver_iob ( struct xfer_interface *socket,
/* Once we're into the data phase, just fill
* the data buffer
*/
rc = http_rx_data ( http, iobuf );
iobuf = NULL;
rc = http_rx_data ( http, iob_disown ( iobuf ) );
goto done;
case HTTP_RX_RESPONSE:
case HTTP_RX_HEADER:

View File

@@ -328,8 +328,7 @@ static int udp_rx ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src,
memset ( &meta, 0, sizeof ( meta ) );
meta.src = ( struct sockaddr * ) st_src;
meta.dest = ( struct sockaddr * ) st_dest;
rc = xfer_deliver_iob_meta ( &udp->xfer, iobuf, &meta );
iobuf = NULL;
rc = xfer_deliver_iob_meta ( &udp->xfer, iob_disown ( iobuf ), &meta );
done:
free_iob ( iobuf );

View File

@@ -976,9 +976,8 @@ static int dhcp_tx ( struct dhcp_session *dhcp ) {
/* Transmit the packet */
iob_put ( iobuf, dhcppkt.len );
rc = xfer_deliver_iob_meta ( &dhcp->xfer, iobuf, &meta );
iobuf = NULL;
if ( rc != 0 ) {
if ( ( rc = xfer_deliver_iob_meta ( &dhcp->xfer, iob_disown ( iobuf ),
&meta ) ) != 0 ) {
DBGC ( dhcp, "DHCP %p could not transmit UDP packet: %s\n",
dhcp, strerror ( rc ) );
goto done;

View File

@@ -763,9 +763,8 @@ static int tftp_rx_data ( struct tftp_request *tftp,
memset ( &meta, 0, sizeof ( meta ) );
meta.whence = SEEK_SET;
meta.offset = offset;
rc = xfer_deliver_iob_meta ( &tftp->xfer, iobuf, &meta );
iobuf = NULL;
if ( rc != 0 ) {
if ( ( rc = xfer_deliver_iob_meta ( &tftp->xfer, iob_disown ( iobuf ),
&meta ) ) != 0 ) {
DBGC ( tftp, "TFTP %p could not deliver data: %s\n",
tftp, strerror ( rc ) );
goto done;
@@ -887,8 +886,7 @@ static int tftp_rx ( struct tftp_request *tftp,
rc = tftp_rx_oack ( tftp, iobuf->data, len );
break;
case htons ( TFTP_DATA ):
rc = tftp_rx_data ( tftp, iobuf );
iobuf = NULL;
rc = tftp_rx_data ( tftp, iob_disown ( iobuf ) );
break;
case htons ( TFTP_ERROR ):
rc = tftp_rx_error ( tftp, iobuf->data, len );