+
+ Log_Debug("Server", "Worker %p", ClientPtr);
+
+ #if USE_TCP
+ while( *((volatile typeof(Client->Socket)*)&Client->Socket) == 0 )
+ ;
+ Threads_SetThread( Client->ClientID );
+
+ while( Client->ClientID != -1 )
+ {
+ fd_set fds;
+ int nfd = Client->Socket+1;
+ FD_ZERO(&fds);
+ FD_SET(Client->Socket, &fds);
+
+ int rv = select(nfd, &fds, NULL, NULL, NULL); // TODO: Timeouts?
+ if(rv < 0) {
+ perror("select");
+ continue ;
+ }
+// Log_Debug("Server", "%p: rv=%i", Client, rv);
+
+ if( FD_ISSET(Client->Socket, &fds) )
+ {
+ const int ciMaxParamCount = 6;
+ char lbuf[sizeof(tRequestHeader) + ciMaxParamCount*sizeof(tRequestValue)];
+ tRequestHeader *hdr = (void*)lbuf;
+ size_t len = recv(Client->Socket, (void*)hdr, sizeof(*hdr), 0);
+// Log_Debug("Server", "%i bytes of header", len);
+ if( len == 0 ) {
+ Log_Notice("Server", "Zero RX on %i (worker %p)", Client->Socket, Client);
+ break;
+ }
+ if( len == -1 ) {
+ perror("recv header");
+// Log_Warning("Server", "recv() error - %s", strerror(errno));
+ break;
+ }
+ if( len != sizeof(*hdr) ) {
+ // Oops?
+ Log_Warning("Server", "FD%i bad sized (%i != exp %i)",
+ Client->Socket, len, sizeof(*hdr));
+ continue ;
+ }
+
+ if( hdr->NParams > ciMaxParamCount ) {
+ // Oops.
+ Log_Warning("Server", "FD%i too many params (%i > max %i)",
+ Client->Socket, hdr->NParams, ciMaxParamCount);
+ break ;
+ }
+
+ if( hdr->NParams > 0 )
+ {
+ len = recv(Client->Socket, (void*)hdr->Params, hdr->NParams*sizeof(tRequestValue), 0);
+// Log_Debug("Server", "%i bytes of params", len);
+ if( len != hdr->NParams*sizeof(tRequestValue) ) {
+ // Oops.
+ perror("recv params");
+ Log_Warning("Sever", "Recieving params failed");
+ break ;
+ }
+ }
+ else
+ {
+// Log_Debug("Server", "No params?");
+ }
+
+ // Get buffer size
+ size_t hdrsize = sizeof(tRequestHeader) + hdr->NParams*sizeof(tRequestValue);
+ size_t bufsize = hdrsize;
+ int i;
+ for( i = 0; i < hdr->NParams; i ++ )
+ {
+ if( hdr->Params[i].Flags & ARG_FLAG_ZEROED )
+ ;
+ else {
+ bufsize += hdr->Params[i].Length;
+ }
+ }
+
+ // Allocate full buffer
+ hdr = malloc(bufsize);
+ memcpy(hdr, lbuf, hdrsize);
+ if( bufsize > hdrsize )
+ {
+ size_t rem = bufsize - hdrsize;
+ char *ptr = (void*)( hdr->Params + hdr->NParams );
+ while( rem )
+ {
+ len = recv(Client->Socket, ptr, rem, 0);
+// Log_Debug("Server", "%i bytes of data", len);
+ if( len == -1 ) {
+ // Oops?
+ perror("recv data");
+ Log_Warning("Sever", "Recieving data failed");
+ break ;
+ }
+ rem -= len;
+ ptr += len;
+ }
+ if( rem ) {
+ break;
+ }
+ }
+// else
+// Log_Debug("Server", "no data");
+
+ int retlen;
+ tRequestHeader *retHeader;
+ retHeader = SyscallRecieve(hdr, &retlen);
+ if( !retHeader ) {
+ // Some sort of error
+ Log_Warning("Server", "SyscallRecieve failed?");
+ continue ;
+ }
+
+ send(Client->Socket, (void*)retHeader, retlen, 0);
+
+ // Clean up
+ free(hdr);
+ }
+ }
+ #else