Sync the bug that list node is free before it is removed from the list. That made the list invalid.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4641 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
vanjeff 2008-01-29 08:47:42 +00:00
parent 7a372cf045
commit 4f6e31e47b
6 changed files with 219 additions and 163 deletions

View File

@ -563,6 +563,7 @@ SockCreate (
ASSERT (SockInitData && SockInitData->ProtoHandler);
ASSERT (SockInitData->Type == SOCK_STREAM);
ASSERT (SockInitData->ProtoData && (SockInitData->DataSize <= PROTO_RESERVED_LEN));
Parent = SockInitData->Parent;
@ -619,6 +620,9 @@ SockCreate (
Sock->Type = SockInitData->Type;
Sock->DriverBinding = SockInitData->DriverBinding;
Sock->State = SockInitData->State;
Sock->CreateCallback = SockInitData->CreateCallback;
Sock->DestroyCallback = SockInitData->DestroyCallback;
Sock->Context = SockInitData->Context;
Sock->SockError = EFI_ABORTED;
Sock->SndBuffer.LowWater = SOCK_BUFF_LOW_WATER;
@ -633,6 +637,11 @@ SockCreate (
sizeof (EFI_TCP4_PROTOCOL)
);
//
// copy the protodata into socket
//
NetCopyMem (Sock->ProtoReserved, SockInitData->ProtoData, SockInitData->DataSize);
Status = gBS->InstallMultipleProtocolInterfaces (
&Sock->SockHandle,
&gEfiTcp4ProtocolGuid,
@ -663,22 +672,36 @@ SockCreate (
NetListInsertTail (&Parent->ConnectionList, &Sock->ConnectionList);
}
if (Sock->CreateCallback != NULL) {
Status = Sock->CreateCallback (Sock, Sock->Context);
if (EFI_ERROR (Status)) {
goto OnError;
}
}
return Sock;
OnError:
if (NULL != Sock) {
if (NULL != Sock->SndBuffer.DataQueue) {
NetbufQueFree (Sock->SndBuffer.DataQueue);
}
if (NULL != Sock->RcvBuffer.DataQueue) {
NetbufQueFree (Sock->RcvBuffer.DataQueue);
}
NetFreePool (Sock);
if (Sock->SockHandle != NULL) {
gBS->UninstallMultipleProtocolInterfaces (
Sock->SockHandle,
&gEfiTcp4ProtocolGuid,
&(Sock->NetProtocol.TcpProtocol),
NULL
);
}
if (NULL != Sock->SndBuffer.DataQueue) {
NetbufQueFree (Sock->SndBuffer.DataQueue);
}
if (NULL != Sock->RcvBuffer.DataQueue) {
NetbufQueFree (Sock->RcvBuffer.DataQueue);
}
NetFreePool (Sock);
return NULL;
}
@ -702,6 +725,10 @@ SockDestroy (
ASSERT (SOCK_STREAM == Sock->Type);
if (Sock->DestroyCallback != NULL) {
Sock->DestroyCallback (Sock, Sock->Context);
}
//
// Flush the completion token buffered
// by sock and rcv, snd buffer
@ -888,6 +915,11 @@ SockClone (
InitData.SndBufferSize = Sock->SndBuffer.HighWater;
InitData.DriverBinding = Sock->DriverBinding;
InitData.Protocol = &(Sock->NetProtocol);
InitData.CreateCallback = Sock->CreateCallback;
InitData.DestroyCallback = Sock->DestroyCallback;
InitData.Context = Sock->Context;
InitData.ProtoData = Sock->ProtoReserved;
InitData.DataSize = sizeof (Sock->ProtoReserved);
ClonedSock = SockCreate (&InitData);
@ -896,12 +928,6 @@ SockClone (
return NULL;
}
NetCopyMem (
ClonedSock->ProtoReserved,
Sock->ProtoReserved,
PROTO_RESERVED_LEN
);
SockSetState (ClonedSock, SO_CONNECTING);
ClonedSock->ConfigureState = Sock->ConfigureState;

View File

@ -214,16 +214,12 @@ SockDestroyChild (
**/
SOCKET *
SockCreateChild (
IN SOCK_INIT_DATA *SockInitData,
IN VOID *ProtoData,
IN UINT32 Len
IN SOCK_INIT_DATA *SockInitData
)
{
SOCKET *Sock;
EFI_STATUS Status;
ASSERT (ProtoData && (Len <= PROTO_RESERVED_LEN));
//
// create a new socket
//
@ -236,15 +232,6 @@ SockCreateChild (
return NULL;
}
//
// Open the
//
//
// copy the protodata into socket
//
NetCopyMem (Sock->ProtoReserved, ProtoData, Len);
Status = NET_TRYLOCK (&(Sock->Lock));
if (EFI_ERROR (Status)) {

View File

@ -211,24 +211,6 @@ typedef struct _SOCK_BUFFER {
NET_BUF_QUEUE *DataQueue; // the queue to buffer data
} SOCK_BUFFER;
//
// the initialize data for create a new socket
//
typedef struct _SOCK_INIT_DATA {
SOCK_TYPE Type;
SOCK_STATE State;
SOCKET *Parent; // the parent of this socket
UINT32 BackLog; // the connection limit for listening socket
UINT32 SndBufferSize; // the high warter mark of send buffer
UINT32 RcvBufferSize; // the high warter mark of receive buffer
VOID *Protocol; // the pointer to protocol function template
// wanted to install on socket
SOCK_PROTO_HANDLER ProtoHandler;
EFI_HANDLE DriverBinding; // the driver binding handle
} SOCK_INIT_DATA;
//
// socket provided oprerations for low layer protocol
@ -317,6 +299,51 @@ SockRcvdErr (
IN EFI_STATUS Error
);
typedef
EFI_STATUS
(*SOCK_CREATE_CALLBACK) (
IN SOCKET *This,
IN VOID *Context
);
typedef
VOID
(*SOCK_DESTROY_CALLBACK) (
IN SOCKET *This,
IN VOID *Context
);
//
// the initialize data for create a new socket
//
typedef struct _SOCK_INIT_DATA {
SOCK_TYPE Type;
SOCK_STATE State;
SOCKET *Parent; // the parent of this socket
UINT32 BackLog; // the connection limit for listening socket
UINT32 SndBufferSize; // the high warter mark of send buffer
UINT32 RcvBufferSize; // the high warter mark of receive buffer
VOID *Protocol; // the pointer to protocol function template
// wanted to install on socket
//
// Callbacks after socket is created and before socket is to be destroyed.
//
SOCK_CREATE_CALLBACK CreateCallback;
SOCK_DESTROY_CALLBACK DestroyCallback;
VOID *Context;
//
// Opaque protocol data.
//
VOID *ProtoData;
UINT32 DataSize;
SOCK_PROTO_HANDLER ProtoHandler;
EFI_HANDLE DriverBinding; // the driver binding handle
} SOCK_INIT_DATA;
//
// the socket structure representing a network service access point
//
@ -368,6 +395,13 @@ struct _SOCKET {
EFI_TCP4_PROTOCOL TcpProtocol;
EFI_UDP4_PROTOCOL UdpProtocol;
} NetProtocol;
//
// Callbacks.
//
SOCK_CREATE_CALLBACK CreateCallback;
SOCK_DESTROY_CALLBACK DestroyCallback;
VOID *Context;
};
//
@ -401,9 +435,7 @@ typedef struct _TCP_RSV_DATA {
//
SOCKET *
SockCreateChild (
IN SOCK_INIT_DATA *SockInitData,
IN VOID *ProtoData,
IN UINT32 Len
IN SOCK_INIT_DATA *SockInitData
);
//

View File

@ -51,6 +51,11 @@ SOCK_INIT_DATA mTcp4DefaultSockData = {
TCP_SND_BUF_SIZE,
TCP_RCV_BUF_SIZE,
&mTcp4ProtocolTemplate,
Tcp4CreateSocketCallback,
Tcp4DestroySocketCallback,
NULL,
NULL,
0,
Tcp4Dispatcher,
NULL,
};
@ -471,6 +476,97 @@ Tcp4DriverBindingStop (
return Status;
}
EFI_STATUS
Tcp4CreateSocketCallback (
IN SOCKET *This,
IN VOID *Context
)
{
EFI_STATUS Status;
TCP4_SERVICE_DATA *TcpServiceData;
EFI_IP4_PROTOCOL *Ip4;
TcpServiceData = ((TCP4_PROTO_DATA *) This->ProtoReserved)->TcpService;
//
// Open the default Ip4 protocol of IP_IO BY_DRIVER.
//
Status = gBS->OpenProtocol (
TcpServiceData->IpIo->ChildHandle,
&gEfiIp4ProtocolGuid,
(VOID **) &Ip4,
TcpServiceData->DriverBindingHandle,
This->SockHandle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Open the device path on the handle where service binding resides on.
//
Status = gBS->OpenProtocol (
TcpServiceData->ControllerHandle,
&gEfiDevicePathProtocolGuid,
(VOID **) &This->ParentDevicePath,
TcpServiceData->DriverBindingHandle,
This->SockHandle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
if (EFI_ERROR (Status)) {
gBS->CloseProtocol (
TcpServiceData->IpIo->ChildHandle,
&gEfiIp4ProtocolGuid,
TcpServiceData->DriverBindingHandle,
This->SockHandle
);
} else {
//
// Insert this socket into the SocketList.
//
NetListInsertTail (&TcpServiceData->SocketList, &This->Link);
}
return Status;
}
VOID
Tcp4DestroySocketCallback (
IN SOCKET *This,
IN VOID *Context
)
{
TCP4_SERVICE_DATA *TcpServiceData;
TcpServiceData = ((TCP4_PROTO_DATA *) This->ProtoReserved)->TcpService;
//
// Remove this node from the list.
//
NetListRemoveEntry (&This->Link);
//
// Close the device path protocol
//
gBS->CloseProtocol (
TcpServiceData->ControllerHandle,
&gEfiDevicePathProtocolGuid,
TcpServiceData->DriverBindingHandle,
This->SockHandle
);
//
// Close the Ip4 protocol.
//
gBS->CloseProtocol (
TcpServiceData->IpIo->ChildHandle,
&gEfiIp4ProtocolGuid,
TcpServiceData->DriverBindingHandle,
This->SockHandle
);
}
/**
Creates a child handle with a set of TCP4 services.
@ -497,7 +593,6 @@ Tcp4ServiceBindingCreateChild (
TCP4_SERVICE_DATA *TcpServiceData;
TCP4_PROTO_DATA TcpProto;
EFI_STATUS Status;
VOID *Ip4;
EFI_TPL OldTpl;
if (NULL == This || NULL == ChildHandle) {
@ -505,6 +600,7 @@ Tcp4ServiceBindingCreateChild (
}
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
Status = EFI_SUCCESS;
TcpServiceData = TCP4_FROM_THIS (This);
TcpProto.TcpService = TcpServiceData;
TcpProto.TcpPcb = NULL;
@ -513,60 +609,20 @@ Tcp4ServiceBindingCreateChild (
// Create a tcp instance with defualt Tcp default
// sock init data and TcpProto
//
mTcp4DefaultSockData.ProtoData = &TcpProto;
mTcp4DefaultSockData.DataSize = sizeof (TCP4_PROTO_DATA);
mTcp4DefaultSockData.DriverBinding = TcpServiceData->DriverBindingHandle;
Sock = SockCreateChild (&mTcp4DefaultSockData, &TcpProto, sizeof (TCP4_PROTO_DATA));
Sock = SockCreateChild (&mTcp4DefaultSockData);
if (NULL == Sock) {
TCP4_DEBUG_ERROR (("Tcp4DriverBindingCreateChild: "
"No resource to create a Tcp Child\n"));
Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
*ChildHandle = Sock->SockHandle;
//
// Open the default Ip4 protocol of IP_IO BY_DRIVER.
//
Status = gBS->OpenProtocol (
TcpServiceData->IpIo->ChildHandle,
&gEfiIp4ProtocolGuid,
(VOID **) &Ip4,
TcpServiceData->DriverBindingHandle,
Sock->SockHandle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
if (EFI_ERROR (Status)) {
SockDestroyChild (Sock);
goto ON_EXIT;
}
//
// Open the device path on the handle where service binding resides on.
//
Status = gBS->OpenProtocol (
TcpServiceData->ControllerHandle,
&gEfiDevicePathProtocolGuid,
(VOID **) &Sock->ParentDevicePath,
TcpServiceData->DriverBindingHandle,
Sock->SockHandle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
if (EFI_ERROR (Status)) {
gBS->CloseProtocol (
TcpServiceData->IpIo->ChildHandle,
&gEfiIp4ProtocolGuid,
TcpServiceData->DriverBindingHandle,
Sock->SockHandle
);
SockDestroyChild (Sock);
} else {
NetListInsertTail (&TcpServiceData->SocketList, &Sock->Link);
*ChildHandle = Sock->SockHandle;
}
ON_EXIT:
NET_RESTORE_TPL (OldTpl);
return Status;
}
@ -594,8 +650,6 @@ Tcp4ServiceBindingDestroyChild (
EFI_STATUS Status;
EFI_TCP4_PROTOCOL *Tcp4;
SOCKET *Sock;
TCP4_PROTO_DATA *TcpProtoData;
TCP4_SERVICE_DATA *TcpServiceData;
EFI_TPL OldTpl;
if (NULL == This || NULL == ChildHandle) {
@ -617,42 +671,17 @@ Tcp4ServiceBindingDestroyChild (
);
if (EFI_ERROR (Status)) {
Status = EFI_UNSUPPORTED;
goto ON_EXIT;
} else {
//
// destroy this sock and related Tcp protocol control
// block
//
Sock = SOCK_FROM_THIS (Tcp4);
SockDestroyChild (Sock);
}
//
// destroy this sock and related Tcp protocol control
// block
//
Sock = SOCK_FROM_THIS (Tcp4);
TcpProtoData = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
TcpServiceData = TcpProtoData->TcpService;
NetListRemoveEntry (&Sock->Link);
SockDestroyChild (Sock);
//
// Close the device path protocol
//
gBS->CloseProtocol (
TcpServiceData->ControllerHandle,
&gEfiDevicePathProtocolGuid,
TcpServiceData->DriverBindingHandle,
ChildHandle
);
//
// Close the Ip4 protocol.
//
gBS->CloseProtocol (
TcpServiceData->IpIo->ChildHandle,
&gEfiIp4ProtocolGuid,
TcpServiceData->DriverBindingHandle,
ChildHandle
);
ON_EXIT:
NET_RESTORE_TPL (OldTpl);
return Status;
}

View File

@ -122,6 +122,18 @@ Tcp4DriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer
);
EFI_STATUS
Tcp4CreateSocketCallback (
IN SOCKET *This,
IN VOID *Context
);
VOID
Tcp4DestroySocketCallback (
IN SOCKET *This,
IN VOID *Context
);
//
// Function ptototypes for the ServiceBinding Prococol
//

View File

@ -425,8 +425,6 @@ TcpCloneTcb (
)
{
TCP_CB *Clone;
TCP4_SERVICE_DATA *TcpService;
EFI_IP4_PROTOCOL *Ip4;
Clone = NetAllocatePool (sizeof (TCP_CB));
@ -455,34 +453,6 @@ TcpCloneTcb (
((TCP4_PROTO_DATA *) (Clone->Sk->ProtoReserved))->TcpPcb = Clone;
TcpService = ((TCP4_PROTO_DATA *) (Clone->Sk->ProtoReserved))->TcpService;
NetListInsertTail (&TcpService->SocketList, &Clone->Sk->Link);
//
// Open the device path on the handle where service binding resides on.
//
gBS->OpenProtocol (
TcpService->ControllerHandle,
&gEfiDevicePathProtocolGuid,
(VOID **) &Clone->Sk->ParentDevicePath,
TcpService->DriverBindingHandle,
Clone->Sk->SockHandle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
//
// Open the ip protocol by child controller.
//
gBS->OpenProtocol (
TcpService->IpIo->ChildHandle,
&gEfiIp4ProtocolGuid,
(VOID **) &Ip4,
TcpService->DriverBindingHandle,
Clone->Sk->SockHandle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
return Clone;
}