netwerk/test/TestOverlappedIO.cpp

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5 #include <stdio.h>
michael@0 6 #include <signal.h>
michael@0 7 #include <algorithm>
michael@0 8
michael@0 9 #ifdef WIN32
michael@0 10 #include <windows.h>
michael@0 11 #endif
michael@0 12
michael@0 13 #include "nspr.h"
michael@0 14 #include "nscore.h"
michael@0 15 #include "nsISocketTransportService.h"
michael@0 16 #include "nsIEventQueueService.h"
michael@0 17 #include "nsIServiceManager.h"
michael@0 18 #include "nsITransport.h"
michael@0 19 #include "nsIRequest.h"
michael@0 20 #include "nsIStreamProvider.h"
michael@0 21 #include "nsIStreamListener.h"
michael@0 22 #include "nsIPipe.h"
michael@0 23 #include "nsIOutputStream.h"
michael@0 24 #include "nsIInputStream.h"
michael@0 25 #include "nsCRT.h"
michael@0 26 #include "nsCOMPtr.h"
michael@0 27 #include "nsIByteArrayInputStream.h"
michael@0 28
michael@0 29 #if defined(PR_LOGGING)
michael@0 30 static PRLogModuleInfo *gTestSocketIOLog;
michael@0 31 #define LOG(args) PR_LOG(gTestSocketIOLog, PR_LOG_DEBUG, args)
michael@0 32 #else
michael@0 33 #define LOG(args)
michael@0 34 #endif
michael@0 35
michael@0 36 static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
michael@0 37 static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
michael@0 38
michael@0 39 static PRTime gElapsedTime;
michael@0 40 static int gKeepRunning = 1;
michael@0 41 static nsIEventQueue* gEventQ = nullptr;
michael@0 42
michael@0 43 //
michael@0 44 //----------------------------------------------------------------------------
michael@0 45 // Test Listener
michael@0 46 //----------------------------------------------------------------------------
michael@0 47 //
michael@0 48
michael@0 49 class TestListener : public nsIStreamListener
michael@0 50 {
michael@0 51 public:
michael@0 52 TestListener() { }
michael@0 53 virtual ~TestListener() {}
michael@0 54
michael@0 55 NS_DECL_ISUPPORTS
michael@0 56 NS_DECL_NSIREQUESTOBSERVER
michael@0 57 NS_DECL_NSISTREAMLISTENER
michael@0 58 };
michael@0 59
michael@0 60 NS_IMPL_ISUPPORTS(TestListener,
michael@0 61 nsIRequestObserver,
michael@0 62 nsIStreamListener);
michael@0 63
michael@0 64 NS_IMETHODIMP
michael@0 65 TestListener::OnStartRequest(nsIRequest* request, nsISupports* context)
michael@0 66 {
michael@0 67 LOG(("TestListener::OnStartRequest\n"));
michael@0 68 return NS_OK;
michael@0 69 }
michael@0 70
michael@0 71 NS_IMETHODIMP
michael@0 72 TestListener::OnDataAvailable(nsIRequest* request,
michael@0 73 nsISupports* context,
michael@0 74 nsIInputStream *aIStream,
michael@0 75 uint64_t aSourceOffset,
michael@0 76 uint32_t aLength)
michael@0 77 {
michael@0 78 LOG(("TestListener::OnDataAvailable [offset=%llu length=%u]\n",
michael@0 79 aSourceOffset, aLength));
michael@0 80 char buf[1025];
michael@0 81 uint32_t amt;
michael@0 82 while (1) {
michael@0 83 aIStream->Read(buf, 1024, &amt);
michael@0 84 if (amt == 0)
michael@0 85 break;
michael@0 86 buf[amt] = '\0';
michael@0 87 //puts(buf);
michael@0 88 printf("read %d bytes\n", amt);
michael@0 89 }
michael@0 90 return NS_OK;
michael@0 91 }
michael@0 92
michael@0 93 NS_IMETHODIMP
michael@0 94 TestListener::OnStopRequest(nsIRequest* request, nsISupports* context,
michael@0 95 nsresult aStatus)
michael@0 96 {
michael@0 97 LOG(("TestListener::OnStopRequest [aStatus=%x]\n", aStatus));
michael@0 98 //gKeepRunning = 0;
michael@0 99 return NS_OK;
michael@0 100 }
michael@0 101
michael@0 102 //
michael@0 103 //----------------------------------------------------------------------------
michael@0 104 // Test Provider
michael@0 105 //----------------------------------------------------------------------------
michael@0 106 //
michael@0 107
michael@0 108 class TestProvider : public nsIStreamProvider
michael@0 109 {
michael@0 110 public:
michael@0 111 TestProvider(char *data);
michael@0 112 virtual ~TestProvider();
michael@0 113
michael@0 114 NS_DECL_ISUPPORTS
michael@0 115 NS_DECL_NSIREQUESTOBSERVER
michael@0 116 NS_DECL_NSISTREAMPROVIDER
michael@0 117
michael@0 118 protected:
michael@0 119 char *mData;
michael@0 120 uint32_t mOffset;
michael@0 121 uint32_t mDataLen;
michael@0 122 uint32_t mRequestCount;
michael@0 123 };
michael@0 124
michael@0 125 NS_IMPL_ISUPPORTS(TestProvider,
michael@0 126 nsIStreamProvider,
michael@0 127 nsIRequestObserver)
michael@0 128
michael@0 129 TestProvider::TestProvider(char *data)
michael@0 130 {
michael@0 131 mData = data;
michael@0 132 mDataLen = strlen(data);
michael@0 133 mOffset = 0;
michael@0 134 mRequestCount = 0;
michael@0 135 LOG(("Constructing TestProvider [this=%p]\n", this));
michael@0 136 }
michael@0 137
michael@0 138 TestProvider::~TestProvider()
michael@0 139 {
michael@0 140 LOG(("Destroying TestProvider [this=%p]\n", this));
michael@0 141 }
michael@0 142
michael@0 143 NS_IMETHODIMP
michael@0 144 TestProvider::OnStartRequest(nsIRequest* request, nsISupports* context)
michael@0 145 {
michael@0 146 LOG(("TestProvider::OnStartRequest [this=%p]\n", this));
michael@0 147 return NS_OK;
michael@0 148 }
michael@0 149
michael@0 150 NS_IMETHODIMP
michael@0 151 TestProvider::OnStopRequest(nsIRequest* request, nsISupports* context,
michael@0 152 nsresult aStatus)
michael@0 153 {
michael@0 154 LOG(("TestProvider::OnStopRequest [status=%x]\n", aStatus));
michael@0 155 return NS_OK;
michael@0 156 }
michael@0 157
michael@0 158 NS_IMETHODIMP
michael@0 159 TestProvider::OnDataWritable(nsIRequest *request, nsISupports *context,
michael@0 160 nsIOutputStream *output, uint32_t offset, uint32_t count)
michael@0 161 {
michael@0 162 LOG(("TestProvider::OnDataWritable [offset=%u, count=%u]\n", offset, count));
michael@0 163
michael@0 164 // Stop at 5 requests
michael@0 165 if (mRequestCount == 5)
michael@0 166 return NS_BASE_STREAM_CLOSED;
michael@0 167
michael@0 168 uint32_t writeCount, amount;
michael@0 169 amount = std::min(count, mDataLen - mOffset);
michael@0 170 nsresult rv = output->Write(mData + mOffset, amount, &writeCount);
michael@0 171 if (NS_SUCCEEDED(rv)) {
michael@0 172 printf("wrote %u bytes\n", writeCount);
michael@0 173 mOffset += writeCount;
michael@0 174 if (mOffset == mDataLen) {
michael@0 175 printf("done sending packet %u\n", mRequestCount);
michael@0 176 mOffset = 0;
michael@0 177 mRequestCount++;
michael@0 178 }
michael@0 179 }
michael@0 180 return NS_OK;
michael@0 181 }
michael@0 182
michael@0 183 //
michael@0 184 //----------------------------------------------------------------------------
michael@0 185 // Synchronous IO
michael@0 186 //----------------------------------------------------------------------------
michael@0 187 //
michael@0 188 nsresult
michael@0 189 WriteRequest(nsIOutputStream *os, const char *request)
michael@0 190 {
michael@0 191 LOG(("WriteRequest [request=%s]\n", request));
michael@0 192 uint32_t n;
michael@0 193 return os->Write(request, strlen(request), &n);
michael@0 194 }
michael@0 195
michael@0 196 nsresult
michael@0 197 ReadResponse(nsIInputStream *is)
michael@0 198 {
michael@0 199 uint32_t bytesRead;
michael@0 200 char buf[2048];
michael@0 201 do {
michael@0 202 is->Read(buf, sizeof(buf), &bytesRead);
michael@0 203 if (bytesRead > 0)
michael@0 204 fwrite(buf, 1, bytesRead, stdout);
michael@0 205 } while (bytesRead > 0);
michael@0 206 return NS_OK;
michael@0 207 }
michael@0 208
michael@0 209 //
michael@0 210 //----------------------------------------------------------------------------
michael@0 211 // Startup...
michael@0 212 //----------------------------------------------------------------------------
michael@0 213 //
michael@0 214
michael@0 215 void
michael@0 216 sighandler(int sig)
michael@0 217 {
michael@0 218 LOG(("got signal: %d\n", sig));
michael@0 219 NS_BREAK();
michael@0 220 }
michael@0 221
michael@0 222 void
michael@0 223 usage(char **argv)
michael@0 224 {
michael@0 225 printf("usage: %s <host> <path>\n", argv[0]);
michael@0 226 exit(1);
michael@0 227 }
michael@0 228
michael@0 229 int
michael@0 230 main(int argc, char* argv[])
michael@0 231 {
michael@0 232 nsresult rv;
michael@0 233
michael@0 234 signal(SIGSEGV, sighandler);
michael@0 235
michael@0 236 #if defined(PR_LOGGING)
michael@0 237 gTestSocketIOLog = PR_NewLogModule("TestSocketIO");
michael@0 238 #endif
michael@0 239
michael@0 240 if (argc < 3)
michael@0 241 usage(argv);
michael@0 242
michael@0 243 char *hostName = argv[1];
michael@0 244 char *fileName = argv[2];
michael@0 245 int port = 80;
michael@0 246
michael@0 247 // Create the Event Queue for this thread...
michael@0 248 nsCOMPtr<nsIEventQueueService> eventQService =
michael@0 249 do_GetService(kEventQueueServiceCID, &rv);
michael@0 250 if (NS_FAILED(rv)) {
michael@0 251 NS_WARNING("failed to create: event queue service!");
michael@0 252 return rv;
michael@0 253 }
michael@0 254
michael@0 255 rv = eventQService->CreateMonitoredThreadEventQueue();
michael@0 256 if (NS_FAILED(rv)) {
michael@0 257 NS_WARNING("failed to create: thread event queue!");
michael@0 258 return rv;
michael@0 259 }
michael@0 260
michael@0 261 eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ);
michael@0 262
michael@0 263 // Create the Socket transport service...
michael@0 264 nsCOMPtr<nsISocketTransportService> sts =
michael@0 265 do_GetService(kSocketTransportServiceCID, &rv);
michael@0 266 if (NS_FAILED(rv)) {
michael@0 267 NS_WARNING("failed to create: socket transport service!");
michael@0 268 return rv;
michael@0 269 }
michael@0 270
michael@0 271 char *buffer = PR_smprintf("GET %s HTTP/1.1" CRLF
michael@0 272 "host: %s" CRLF
michael@0 273 "user-agent: Mozilla/5.0 (X11; N; Linux 2.2.16-22smp i686; en-US; m18) Gecko/20001220" CRLF
michael@0 274 "accept: */*" CRLF
michael@0 275 "accept-language: en" CRLF
michael@0 276 "accept-encoding: gzip,deflate,compress,identity" CRLF
michael@0 277 "keep-alive: 300" CRLF
michael@0 278 "connection: keep-alive" CRLF
michael@0 279 CRLF,
michael@0 280 fileName, hostName);
michael@0 281 LOG(("Request [\n%s]\n", buffer));
michael@0 282
michael@0 283 // Create the socket transport...
michael@0 284 nsCOMPtr<nsITransport> transport;
michael@0 285 rv = sts->CreateTransport(hostName, port, nullptr, -1, 0, 0, getter_AddRefs(transport));
michael@0 286 if (NS_FAILED(rv)) {
michael@0 287 NS_WARNING("failed to create: socket transport!");
michael@0 288 return rv;
michael@0 289 }
michael@0 290
michael@0 291 gElapsedTime = PR_Now();
michael@0 292
michael@0 293 nsCOMPtr<nsIRequest> writeRequest, readRequest;
michael@0 294
michael@0 295 rv = transport->AsyncWrite(new TestProvider(buffer), nullptr, 0, 0, 0, getter_AddRefs(writeRequest));
michael@0 296 if (NS_FAILED(rv)) {
michael@0 297 NS_WARNING("failed calling: AsyncWrite!");
michael@0 298 return rv;
michael@0 299 }
michael@0 300 rv = transport->AsyncRead(new TestListener(), nullptr, 0, 0, 0, getter_AddRefs(readRequest));
michael@0 301 if (NS_FAILED(rv)) {
michael@0 302 NS_WARNING("failed calling: AsyncWrite!");
michael@0 303 return rv;
michael@0 304 }
michael@0 305
michael@0 306 // Enter the message pump
michael@0 307 while ( gKeepRunning ) {
michael@0 308 PLEvent *gEvent;
michael@0 309 gEventQ->WaitForEvent(&gEvent);
michael@0 310 gEventQ->HandleEvent(gEvent);
michael@0 311 }
michael@0 312
michael@0 313 PRTime endTime;
michael@0 314 endTime = PR_Now();
michael@0 315 LOG(("Elapsed time: %d\n", (int32_t)(endTime/1000UL - gElapsedTime/1000UL)));
michael@0 316
michael@0 317 sts->Shutdown();
michael@0 318 return 0;
michael@0 319 }

mercurial