svn commit: samba r3307 - in branches/SAMBA_4_0/source/smb_server: .

tridge at samba.org tridge at samba.org
Thu Oct 28 05:09:43 GMT 2004


Author: tridge
Date: 2004-10-28 05:09:42 +0000 (Thu, 28 Oct 2004)
New Revision: 3307

WebSVN: http://websvn.samba.org/websvn/changeset.php?rep=samba&path=/branches/SAMBA_4_0/source/smb_server&rev=3307&nolog=1

Log:
fixed the send side of the smb_server code to be non-blocking. This
means the whole of the SMB handling code is now non-blocking.

Modified:
   branches/SAMBA_4_0/source/smb_server/request.c
   branches/SAMBA_4_0/source/smb_server/smb_server.c
   branches/SAMBA_4_0/source/smb_server/smb_server.h


Changeset:
Modified: branches/SAMBA_4_0/source/smb_server/request.c
===================================================================
--- branches/SAMBA_4_0/source/smb_server/request.c	2004-10-28 04:36:12 UTC (rev 3306)
+++ branches/SAMBA_4_0/source/smb_server/request.c	2004-10-28 05:09:42 UTC (rev 3307)
@@ -241,24 +241,16 @@
 */
 void req_send_reply_nosign(struct smbsrv_request *req)
 {
-	NTSTATUS status;
-	DATA_BLOB tmp_blob;
-	size_t sendlen;
-
 	if (req->out.size > NBT_HDR_SIZE) {
 		_smb_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE);
 	}
 
-	tmp_blob.data = req->out.buffer;
-	tmp_blob.length = req->out.size;
+	/* add the request to the list of requests that need to be
+	   sent to the client, then mark the socket event structure
+	   ready for write events */
+	DLIST_ADD_END(req->smb_conn->pending_send, req, struct smbsrv_request *);
 
-	status = socket_send(req->smb_conn->connection->socket, &tmp_blob, &sendlen, SOCKET_FLAG_BLOCK);
-	if (!NT_STATUS_IS_OK(status) || (req->out.size != sendlen)) {
-		smbsrv_terminate_connection(req->smb_conn, "failed to send reply\n");
-		return;
-	}
-
-	req_destroy(req);
+	req->smb_conn->connection->event.fde->flags |= EVENT_FD_WRITE;
 }
 
 /*

Modified: branches/SAMBA_4_0/source/smb_server/smb_server.c
===================================================================
--- branches/SAMBA_4_0/source/smb_server/smb_server.c	2004-10-28 04:36:12 UTC (rev 3306)
+++ branches/SAMBA_4_0/source/smb_server/smb_server.c	2004-10-28 05:09:42 UTC (rev 3307)
@@ -804,8 +804,42 @@
 */
 static void smbsrv_send(struct server_connection *conn, time_t t, uint16_t flags)
 {
-	DEBUG(10,("smbsrv_send\n"));
-	return;
+	struct smbsrv_connection *smb_conn = conn->private_data;
+
+	while (smb_conn->pending_send) {
+		struct smbsrv_request *req = smb_conn->pending_send;
+		DATA_BLOB blob;
+		NTSTATUS status;
+		size_t sendlen;
+
+		blob.data = req->out.buffer;
+		blob.length = req->out.size;
+
+		/* send as much of this request as we can */
+		status = socket_send(conn->socket, &blob, &sendlen, 0);
+		if (NT_STATUS_IS_ERR(status)) {
+			smbsrv_terminate_connection(req->smb_conn, nt_errstr(status));
+			return;
+		}
+		if (sendlen == 0) {
+			break;
+		}
+
+		req->out.buffer += sendlen;
+		req->out.size -= sendlen;
+
+		/* is the whole request gone? */
+		if (req->out.size == 0) {
+			DLIST_REMOVE(smb_conn->pending_send, req);
+			req_destroy(req);
+		}
+	}
+
+	/* if no more requests are pending to be sent then
+	   we should stop select for write */
+	if (smb_conn->pending_send == NULL) {
+		conn->event.fde->flags &= ~EVENT_FD_WRITE;
+	}
 }
 
 /*
@@ -860,11 +894,9 @@
 
 	DEBUG(5,("smbsrv_accept\n"));
 
-	smb_conn = talloc_p(conn, struct smbsrv_connection);
+	smb_conn = talloc_zero_p(conn, struct smbsrv_connection);
 	if (!smb_conn) return;
 
-	ZERO_STRUCTP(smb_conn);
-
 	smb_conn->pid = getpid();
 
 	sub_set_context(&smb_conn->substitute);

Modified: branches/SAMBA_4_0/source/smb_server/smb_server.h
===================================================================
--- branches/SAMBA_4_0/source/smb_server/smb_server.h	2004-10-28 04:36:12 UTC (rev 3306)
+++ branches/SAMBA_4_0/source/smb_server/smb_server.h	2004-10-28 05:09:42 UTC (rev 3307)
@@ -74,6 +74,9 @@
 /* the context for a single SMB request. This is passed to any request-context 
    functions */
 struct smbsrv_request {
+	/* the smbsrv_connection needs a list of requests queued for send */
+	struct smbsrv_request *next, *prev;
+
 	/* the server_context contains all context specific to this SMB socket */
 	struct smbsrv_connection *smb_conn;
 
@@ -289,4 +292,8 @@
 
 	/* this holds a partially received request */
 	struct smbsrv_request *partial_req;
+
+	/* this holds list of replies that are waiting to be sent
+	   to the client */
+	struct smbsrv_request *pending_send;
 };



More information about the samba-cvs mailing list