Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

117 lines
6.2 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // download_internal.h
  4. //
  5. // Header file for optional HTTP asset downloading
  6. // Author: Matthew D. Campbell ([email protected]), 2004
  7. //
  8. //=======================================================================================//
  9. #ifndef DOWNLOAD_INTERNAL_H
  10. #define DOWNLOAD_INTERNAL_H
  11. /**
  12. * -------------------
  13. * Download overview:
  14. * HTTP downloading is done outside the main thread, to increase responsiveness
  15. * and for code clarity (the download can be a linear sequence of blocking calls).
  16. *
  17. * The process is as follows, from the perspective of the main thread:
  18. * 1. Downloads are queued up when connecting to a server, if the server sends
  19. * a download URL.
  20. * 2. If HTTP downloads are queued up, the client disconnects from the server,
  21. * and puts up a progress bar dialog box for the transfers.
  22. * 3. The CL_HTTPUpdate() function is called every frame, and it does the following:
  23. * a) Starts a download thread if none are active, and at least one is queued up.
  24. * b) Checks on status of the current transfer and updates the progress bar.
  25. * i. If the thread has finished, the file is written out to disk and another
  26. * transfer is started.
  27. * ii. If the thread has aborted/errored out, any partial data is written to
  28. * the cache, the progress bar is removed, and an error message is
  29. * shown, if neccessary.
  30. * c) Checks for old transfers to clean up where the download thread has exited.
  31. * 4. If the user hits Cancel on the progress bar, the current download is told to
  32. * abort, and the progress bar is removed.
  33. *
  34. * The process is as follows, from the perspective of the download thread:
  35. * 1. A complete URL is constructed and verified for correctness.
  36. * 2. The connection is established with the server.
  37. * 3. The file is requested from the server, including the file timestamp and
  38. * byte range for partial transfers (resuming an aborted transfer). A buffer
  39. * for the data is allocated in this thread.
  40. * 4. while the main thread has not requested an abort, read data from the server.
  41. * 5. Upon completion, abort, or an error, the thread does the following:
  42. * a) close any open handles
  43. * b) wait for the main thread to request an exit (so the main thread can read
  44. * any data.)
  45. * c) delete the data buffer (previously allocated in this thread)
  46. * d) sets a flag letting the main thread know this thread is finished.
  47. * e) exit
  48. *
  49. * -------------------
  50. * Thread interaction:
  51. * All thread interaction is handled via a shared RequestContext_t. Interaction is
  52. * structured so that at all times, only one thread can be writing to any given
  53. * variable.
  54. *
  55. * This is an attempt to enumerate all cases of thread interaction:
  56. * 1. Before download thread creation
  57. * a) main thread allocates the RequestContext_t, and zeroes it out.
  58. * b) main thread fills in the baseURL and gamePath strings.
  59. * c) main thread sets cachedTimestamp, nBytesCached, and allocates/fills
  60. * cacheData if there is data from a previous aborted download.
  61. * 2. During thread operation:
  62. * a) download thread can do the following:
  63. * i. for HTTP_CONNECTING, download thread can set nBytesTotal,
  64. * nBytesCached, and nBytesCurrent. It can allocate data, and
  65. * set the status to HTTP_FETCH, HTTP_ABORTED, or HTTP_ERROR.
  66. * ii. for HTTP_FETCH, download thread can write to data, set
  67. * nBytesCurrent, and set status to HTTP_DONE, HTTP_ABORTED,
  68. * or HTTP_ERROR.
  69. * iii. for HTTP_DONE, HTTP_ABORTED, and HTTP_ERROR, the download thread
  70. * can only look at shouldStop until it is set by the main thread.
  71. * b) main thread can look at status.
  72. * i. for HTTP_CONNECTING, nothing is read, and only shouldStop can be set.
  73. * ii. for HTTP_FETCH, nBytesTotal and nBytesCurrent are read, and
  74. * shouldStop can be set.
  75. * iii. for HTTP_DONE, nBytesTotal, nBytesCurrent, and data are read. Also,
  76. * shouldStop can be set.
  77. * iv. for HTTP_ABORTED, nothing is read, and only shouldStop can be set.
  78. * v. for HTTP_ERROR, nBytesTotal, nBytesCurrent, and data are read. Also,
  79. * shouldStop can be set.
  80. * 3. After shouldStop is set by main thread:
  81. * a) if the download thread is in status HTTP_FETCH, it will cease operations
  82. * and set status to HTTP_ABORTED.
  83. * b) download thread will delete data, if it exists.
  84. * c) download thread will set threadDone.
  85. * d) after the main thread set shouldStop, it will only look at threadDone.
  86. * 4. After threadDone is set by download thread:
  87. * a) download thread can safely exit, and will not access the RequestContext_t.
  88. * b) main thread can delete the cacheData, if any exists, and delete the
  89. * RequestContext_t itself. Thus ends the download.
  90. * 5. SPECIAL CASE: if the user hits Cancel during a download, the main thread will
  91. * look at nBytesTotal and nBytesCurrent to determine if there is any data
  92. * present, and read from data if there is. The download thread will most likely
  93. * be in HTTP_CONNECTING or HTTP_FETCH, but could also be in HTTP_DONE or
  94. * HTTP_ERROR at this time. Regardless, this should be safe because of the
  95. * following reasons:
  96. * a) if nBytesCurrent is non-zero, this means data has been allocated, and
  97. * nBytesTotal has been set and won't change.
  98. * b) nBytesCurrent increases monotonically, so the contents of
  99. * data[0..nBytesCurrent] is complete and unchanging.
  100. *
  101. */
  102. //--------------------------------------------------------------------------------------------------------------
  103. #include "engine/requestcontext.h"
  104. //--------------------------------------------------------------------------------------------------------------
  105. #ifdef POSIX
  106. void DownloadThread( void *voidPtr );
  107. #else
  108. DWORD __stdcall DownloadThread( void *voidPtr );
  109. #endif
  110. #endif // DOWNLOAD_INTERNAL_H
  111. //--------------------------------------------------------------------------------------------------------------