mirror of https://github.com/acidanthera/audk.git
Fixed close for socket to properly release the socket context structure and the handle.
Signed-off-by: lpleahy git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13802 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
e06a4cd134
commit
4652be0c5a
|
@ -31,7 +31,6 @@ BslSocketCloseWork (
|
||||||
IN int * pErrno
|
IN int * pErrno
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;
|
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -50,21 +49,9 @@ BslSocketCloseWork (
|
||||||
}
|
}
|
||||||
if ( !EFI_ERROR ( Status )) {
|
if ( !EFI_ERROR ( Status )) {
|
||||||
//
|
//
|
||||||
// Locate the socket protocol
|
// Release the socket resources
|
||||||
//
|
//
|
||||||
Status = gBS->LocateProtocol ( &gEfiSocketServiceBindingProtocolGuid,
|
*pErrno = EslServiceFreeProtocol ( pSocketProtocol );
|
||||||
NULL,
|
|
||||||
(VOID **) &pServiceBinding );
|
|
||||||
if ( !EFI_ERROR ( Status )) {
|
|
||||||
//
|
|
||||||
// Release the handle
|
|
||||||
//
|
|
||||||
Status = pServiceBinding->DestroyChild ( pServiceBinding,
|
|
||||||
pSocketProtocol->SocketHandle );
|
|
||||||
}
|
|
||||||
if ( EFI_ERROR ( Status )) {
|
|
||||||
*pErrno = EIO;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DEBUG (( DEBUG_ERROR,
|
DEBUG (( DEBUG_ERROR,
|
||||||
|
|
|
@ -91,11 +91,8 @@ EslDxeDestroyChild (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ESL_LAYER * pLayer;
|
ESL_LAYER * pLayer;
|
||||||
ESL_SOCKET * pSocket;
|
|
||||||
ESL_SOCKET * pSocketPrevious;
|
|
||||||
EFI_SOCKET_PROTOCOL * pSocketProtocol;
|
EFI_SOCKET_PROTOCOL * pSocketProtocol;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_TPL TplPrevious;
|
|
||||||
|
|
||||||
DBG_ENTER ( );
|
DBG_ENTER ( );
|
||||||
|
|
||||||
|
@ -112,101 +109,10 @@ EslDxeDestroyChild (
|
||||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||||
);
|
);
|
||||||
if ( !EFI_ERROR ( Status )) {
|
if ( !EFI_ERROR ( Status )) {
|
||||||
pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Synchronize with the socket layer
|
// Free the socket resources
|
||||||
//
|
//
|
||||||
RAISE_TPL ( TplPrevious, TPL_SOCKETS );
|
Status = EslSocketFree ( pSocketProtocol, NULL );
|
||||||
|
|
||||||
//
|
|
||||||
// Walk the socket list
|
|
||||||
//
|
|
||||||
pSocketPrevious = pLayer->pSocketList;
|
|
||||||
if ( NULL != pSocketPrevious ) {
|
|
||||||
if ( pSocket == pSocketPrevious ) {
|
|
||||||
//
|
|
||||||
// Remove the socket from the head of the list
|
|
||||||
//
|
|
||||||
pLayer->pSocketList = pSocket->pNext;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//
|
|
||||||
// Find the socket in the middle of the list
|
|
||||||
//
|
|
||||||
while (( NULL != pSocketPrevious )
|
|
||||||
&& ( pSocket != pSocketPrevious->pNext )) {
|
|
||||||
//
|
|
||||||
// Set the next socket
|
|
||||||
//
|
|
||||||
pSocketPrevious = pSocketPrevious->pNext;
|
|
||||||
}
|
|
||||||
if ( NULL != pSocketPrevious ) {
|
|
||||||
//
|
|
||||||
// Remove the socket from the middle of the list
|
|
||||||
//
|
|
||||||
pSocketPrevious = pSocket->pNext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DEBUG (( DEBUG_ERROR | DEBUG_POOL,
|
|
||||||
"ERROR - Socket list is empty!\r\n" ));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Release the socket layer synchronization
|
|
||||||
//
|
|
||||||
RESTORE_TPL ( TplPrevious );
|
|
||||||
|
|
||||||
//
|
|
||||||
// Determine if the socket was found
|
|
||||||
//
|
|
||||||
if ( NULL != pSocketPrevious ) {
|
|
||||||
pSocket->pNext = NULL;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Remove the socket protocol
|
|
||||||
//
|
|
||||||
Status = gBS->UninstallMultipleProtocolInterfaces (
|
|
||||||
ChildHandle,
|
|
||||||
&gEfiSocketProtocolGuid,
|
|
||||||
&pSocket->SocketProtocol,
|
|
||||||
NULL );
|
|
||||||
if ( !EFI_ERROR ( Status )) {
|
|
||||||
DEBUG (( DEBUG_POOL | DEBUG_INFO,
|
|
||||||
"Removed: gEfiSocketProtocolGuid from 0x%08x\r\n",
|
|
||||||
ChildHandle ));
|
|
||||||
|
|
||||||
//
|
|
||||||
// Free the socket structure
|
|
||||||
//
|
|
||||||
Status = gBS->FreePool ( pSocket );
|
|
||||||
if ( !EFI_ERROR ( Status )) {
|
|
||||||
DEBUG (( DEBUG_POOL,
|
|
||||||
"0x%08x: Free pSocket, %d bytes\r\n",
|
|
||||||
pSocket,
|
|
||||||
sizeof ( *pSocket )));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DEBUG (( DEBUG_ERROR | DEBUG_POOL,
|
|
||||||
"ERROR - Failed to free pSocket 0x%08x, Status: %r\r\n",
|
|
||||||
pSocket,
|
|
||||||
Status ));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INFO,
|
|
||||||
"ERROR - Failed to remove gEfiSocketProtocolGuid from 0x%08x, Status: %r\r\n",
|
|
||||||
ChildHandle,
|
|
||||||
Status ));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DEBUG (( DEBUG_ERROR | DEBUG_INFO,
|
|
||||||
"ERROR - The socket was not in the socket list!\r\n" ));
|
|
||||||
Status = EFI_NOT_FOUND;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DEBUG (( DEBUG_ERROR,
|
DEBUG (( DEBUG_ERROR,
|
||||||
|
|
|
@ -1945,6 +1945,168 @@ EslSocketCopyFragmentedBuffer (
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Free the socket.
|
||||||
|
|
||||||
|
This routine frees the socket structure and handle resources.
|
||||||
|
|
||||||
|
The ::close routine calls EslServiceFreeProtocol which then calls
|
||||||
|
this routine to free the socket context structure and close the
|
||||||
|
handle.
|
||||||
|
|
||||||
|
@param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.
|
||||||
|
|
||||||
|
@param [out] pErrno Address to receive the errno value upon completion.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The socket resources were returned successfully.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EslSocketFree (
|
||||||
|
IN EFI_SOCKET_PROTOCOL * pSocketProtocol,
|
||||||
|
IN int * pErrno
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_HANDLE ChildHandle;
|
||||||
|
int errno;
|
||||||
|
ESL_LAYER * pLayer;
|
||||||
|
ESL_SOCKET * pSocket;
|
||||||
|
ESL_SOCKET * pSocketPrevious;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_TPL TplPrevious;
|
||||||
|
|
||||||
|
DBG_ENTER ( );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Assume failure
|
||||||
|
//
|
||||||
|
errno = EIO;
|
||||||
|
pSocket = NULL;
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate the socket
|
||||||
|
//
|
||||||
|
pLayer = &mEslLayer;
|
||||||
|
if ( NULL != pSocketProtocol ) {
|
||||||
|
pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Synchronize with the socket layer
|
||||||
|
//
|
||||||
|
RAISE_TPL ( TplPrevious, TPL_SOCKETS );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Walk the socket list
|
||||||
|
//
|
||||||
|
pSocketPrevious = pLayer->pSocketList;
|
||||||
|
if ( NULL != pSocketPrevious ) {
|
||||||
|
if ( pSocket == pSocketPrevious ) {
|
||||||
|
//
|
||||||
|
// Remove the socket from the head of the list
|
||||||
|
//
|
||||||
|
pLayer->pSocketList = pSocket->pNext;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//
|
||||||
|
// Find the socket in the middle of the list
|
||||||
|
//
|
||||||
|
while (( NULL != pSocketPrevious )
|
||||||
|
&& ( pSocket != pSocketPrevious->pNext )) {
|
||||||
|
//
|
||||||
|
// Set the next socket
|
||||||
|
//
|
||||||
|
pSocketPrevious = pSocketPrevious->pNext;
|
||||||
|
}
|
||||||
|
if ( NULL != pSocketPrevious ) {
|
||||||
|
//
|
||||||
|
// Remove the socket from the middle of the list
|
||||||
|
//
|
||||||
|
pSocketPrevious = pSocket->pNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DEBUG (( DEBUG_ERROR | DEBUG_POOL,
|
||||||
|
"ERROR - Socket list is empty!\r\n" ));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Release the socket layer synchronization
|
||||||
|
//
|
||||||
|
RESTORE_TPL ( TplPrevious );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Determine if the socket was found
|
||||||
|
//
|
||||||
|
if ( NULL != pSocketPrevious ) {
|
||||||
|
pSocket->pNext = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove the socket protocol
|
||||||
|
//
|
||||||
|
ChildHandle = pSocket->SocketProtocol.SocketHandle;
|
||||||
|
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||||
|
ChildHandle,
|
||||||
|
&gEfiSocketProtocolGuid,
|
||||||
|
&pSocket->SocketProtocol,
|
||||||
|
NULL );
|
||||||
|
if ( !EFI_ERROR ( Status )) {
|
||||||
|
DEBUG (( DEBUG_POOL | DEBUG_INFO,
|
||||||
|
"Removed: gEfiSocketProtocolGuid from 0x%08x\r\n",
|
||||||
|
ChildHandle ));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Free the socket structure
|
||||||
|
//
|
||||||
|
Status = gBS->FreePool ( pSocket );
|
||||||
|
if ( !EFI_ERROR ( Status )) {
|
||||||
|
DEBUG (( DEBUG_POOL,
|
||||||
|
"0x%08x: Free pSocket, %d bytes\r\n",
|
||||||
|
pSocket,
|
||||||
|
sizeof ( *pSocket )));
|
||||||
|
errno = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DEBUG (( DEBUG_ERROR | DEBUG_POOL,
|
||||||
|
"ERROR - Failed to free pSocket 0x%08x, Status: %r\r\n",
|
||||||
|
pSocket,
|
||||||
|
Status ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INFO,
|
||||||
|
"ERROR - Failed to remove gEfiSocketProtocolGuid from 0x%08x, Status: %r\r\n",
|
||||||
|
ChildHandle,
|
||||||
|
Status ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DEBUG (( DEBUG_ERROR | DEBUG_INFO,
|
||||||
|
"ERROR - The socket was not in the socket list!\r\n" ));
|
||||||
|
Status = EFI_NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DEBUG (( DEBUG_ERROR,
|
||||||
|
"ERROR - Invalid parameter pSocketProtocol is NULL\r\n" ));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return the errno value if possible
|
||||||
|
//
|
||||||
|
if ( NULL != pErrno ) {
|
||||||
|
*pErrno = errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return the operation status
|
||||||
|
//
|
||||||
|
DBG_EXIT_STATUS ( Status );
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the local address.
|
Get the local address.
|
||||||
|
|
||||||
|
|
|
@ -1187,6 +1187,28 @@ EslSocketCopyFragmentedBuffer (
|
||||||
OUT size_t * pDataLength
|
OUT size_t * pDataLength
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Free the socket.
|
||||||
|
|
||||||
|
This routine frees the socket structure and handle resources.
|
||||||
|
|
||||||
|
The ::close routine calls EslServiceFreeProtocol which then calls
|
||||||
|
this routine to free the socket context structure and close the
|
||||||
|
handle.
|
||||||
|
|
||||||
|
@param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.
|
||||||
|
|
||||||
|
@param [out] pErrno Address to receive the errno value upon completion.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The socket resources were returned successfully.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EslSocketFree (
|
||||||
|
IN EFI_SOCKET_PROTOCOL * pSocketProtocol,
|
||||||
|
IN int * pErrno
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Free the ESL_IO_MGMT event and structure
|
Free the ESL_IO_MGMT event and structure
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,40 @@ CONST EFI_GUID mEslUdp6ServiceGuid __attribute__((weak)) = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Free the socket resources
|
||||||
|
|
||||||
|
This releases the socket resources allocated by calling
|
||||||
|
EslServiceGetProtocol.
|
||||||
|
|
||||||
|
This routine is called from the ::close routine in BsdSocketLib
|
||||||
|
to release the socket resources.
|
||||||
|
|
||||||
|
@param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL
|
||||||
|
structure
|
||||||
|
|
||||||
|
@return Value for ::errno, zero (0) indicates success.
|
||||||
|
|
||||||
|
**/
|
||||||
|
int
|
||||||
|
EslServiceFreeProtocol (
|
||||||
|
IN EFI_SOCKET_PROTOCOL * pSocketProtocol
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int RetVal;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Release the socket resources
|
||||||
|
//
|
||||||
|
EslSocketFree ( pSocketProtocol, &RetVal );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return the operation status
|
||||||
|
//
|
||||||
|
return RetVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Connect to the EFI socket library
|
Connect to the EFI socket library
|
||||||
|
|
||||||
|
|
|
@ -612,6 +612,26 @@ AcceptNB (
|
||||||
socklen_t * address_len
|
socklen_t * address_len
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Free the socket resources
|
||||||
|
|
||||||
|
This releases the socket resources allocated by calling
|
||||||
|
EslServiceGetProtocol.
|
||||||
|
|
||||||
|
This routine is called from the ::close routine in BsdSocketLib
|
||||||
|
to release the socket resources.
|
||||||
|
|
||||||
|
@param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL
|
||||||
|
structure
|
||||||
|
|
||||||
|
@return Value for ::errno, zero (0) indicates success.
|
||||||
|
|
||||||
|
**/
|
||||||
|
int
|
||||||
|
EslServiceFreeProtocol (
|
||||||
|
IN EFI_SOCKET_PROTOCOL * pSocketProtocol
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Connect to the EFI socket library
|
Connect to the EFI socket library
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,59 @@
|
||||||
#include <Protocol/ServiceBinding.h>
|
#include <Protocol/ServiceBinding.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Free the socket resources
|
||||||
|
|
||||||
|
This releases the socket resources allocated by calling
|
||||||
|
EslServiceGetProtocol.
|
||||||
|
|
||||||
|
This routine is called from the ::close routine in BsdSocketLib
|
||||||
|
to release the socket resources.
|
||||||
|
|
||||||
|
@param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL
|
||||||
|
structure
|
||||||
|
|
||||||
|
@return Value for ::errno, zero (0) indicates success.
|
||||||
|
|
||||||
|
**/
|
||||||
|
int
|
||||||
|
EslServiceFreeProtocol (
|
||||||
|
IN EFI_SOCKET_PROTOCOL * pSocketProtocol
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;
|
||||||
|
int RetVal;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Assume success
|
||||||
|
//
|
||||||
|
RetVal = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Locate the socket protocol
|
||||||
|
//
|
||||||
|
Status = gBS->LocateProtocol ( &gEfiSocketServiceBindingProtocolGuid,
|
||||||
|
NULL,
|
||||||
|
(VOID **) &pServiceBinding );
|
||||||
|
if ( !EFI_ERROR ( Status )) {
|
||||||
|
//
|
||||||
|
// Release the handle
|
||||||
|
//
|
||||||
|
Status = pServiceBinding->DestroyChild ( pServiceBinding,
|
||||||
|
pSocketProtocol->SocketHandle );
|
||||||
|
}
|
||||||
|
if ( EFI_ERROR ( Status )) {
|
||||||
|
RetVal = EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return the operation status
|
||||||
|
//
|
||||||
|
return RetVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Connect to the EFI socket library
|
Connect to the EFI socket library
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue