llcorehttpoperation.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /**
  2. * @file llcorehttpoperation.h
  3. * @brief Internal declarations for HttpOperation and sub-classes
  4. *
  5. * $LicenseInfo:firstyear=2012&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2012, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #ifndef _LLCORE_HTTP_OPERATION_H_
  27. #define _LLCORE_HTTP_OPERATION_H_
  28. #include "llcorehttpcommon.h"
  29. #include "llcorehttprequest.h"
  30. #include "llcoremutex.h"
  31. #include "llerror.h"
  32. namespace LLCore
  33. {
  34. class HttpReplyQueue;
  35. class HttpHandler;
  36. class HttpService;
  37. // HttpOperation is the base class for all request/reply pairs.
  38. //
  39. // Operations are expected to be of two types: immediate and queued. Immediate
  40. // requests go to the singleton request queue and when picked up by the worker
  41. // thread are executed immediately and there results placed on the supplied
  42. // reply queue. Queued requests (namely for HTTP operations), go to the
  43. // request queue, are picked up and moved to a ready and managed by the policy
  44. // component, are then activated issuing HTTP requests and moved to an active
  45. // list managed by the transport (libcurl) component and eventually finalized
  46. // when a response is available and status and data return via reply queue.
  47. //
  48. // To manage these transitions, derived classes implement three methods:
  49. // stageFromRequest, stageFromReady and stageFromActive. Immediate requests
  50. // will only override stageFromRequest which will perform the operation and
  51. // return the result by invoking addAsReply() to put the request on a reply
  52. // queue. Queued requests will involve all three stage methods.
  53. //
  54. // Threading: not thread-safe. Base and derived classes provide no locking.
  55. // Instances move across threads via queue-like interfaces that are thread
  56. // compatible and those interfaces establish the access rules.
  57. class HttpOperation : public std::enable_shared_from_this<HttpOperation>
  58. {
  59. protected:
  60. LOG_CLASS(HttpOperation);
  61. public:
  62. typedef std::shared_ptr<HttpOperation> ptr_t;
  63. typedef std::weak_ptr<HttpOperation> wptr_t;
  64. typedef std::shared_ptr<HttpReplyQueue> HttpReplyQueuePtr_t;
  65. // Threading: called by a consumer thread.
  66. HttpOperation();
  67. // Threading: called by any thread.
  68. virtual ~HttpOperation(); // Use release()
  69. // Non-copyable
  70. HttpOperation(const HttpOperation&) = delete;
  71. HttpOperation& operator=(const HttpOperation&) = delete;
  72. public:
  73. // Register a reply queue and a handler for completion notifications.
  74. //
  75. // Invokers of operations that want to receive notification that an
  76. // operation has been completed do so by binding a reply queue and a
  77. // handler object to the request.
  78. //
  79. // @param reply_queue Pointer to the reply queue where completion
  80. // notifications are to be queued (typically by
  81. // addAsReply()). This will typically be the reply
  82. // queue referenced by the request object. This
  83. // method will increment the refcount on the queue
  84. // holding the queue until delivery is complete.
  85. // Using a reply_queue even if the handler is NULL
  86. // has some benefits for memory deallocation by
  87. // keeping it in the originating thread.
  88. //
  89. // @param handler Possibly NULL pointer to a non-refcounted
  90. // handler object to be invoked (onCompleted) when
  91. // the operation is finished. Note that the
  92. // handler object is never dereferenced by the
  93. // worker thread. This is passible data until
  94. // notification is performed.
  95. //
  96. // Threading: called by consumer thread.
  97. //
  98. void setReplyPath(HttpReplyQueuePtr_t reply_queue,
  99. HttpHandler::ptr_t handler);
  100. // The three possible staging steps in an operation's lifecycle.
  101. // Asynchronous requests like HTTP operations move from the request queue
  102. // to the ready queue via stageFromRequest. Then from the ready queue to
  103. // the active queue by stageFromReady. And when complete, to the reply
  104. // queue via stageFromActive and the addAsReply utility.
  105. //
  106. // Immediate mode operations (everything else) move from the request queue
  107. // to the reply queue directly via stageFromRequest and addAsReply with no
  108. // existence on the ready or active queues.
  109. //
  110. // These methods will take out a reference count on the request, caller
  111. // only needs to dispose of its reference when done with the request.
  112. //
  113. // Threading: called by worker thread.
  114. //
  115. virtual void stageFromRequest(HttpService*);
  116. virtual void stageFromReady(HttpService*);
  117. virtual void stageFromActive(HttpService*);
  118. // Delivers a notification to a handler object on completion.
  119. //
  120. // Once a request is complete and it has been removed from its reply queue,
  121. // a handler notification may be delivered by a call to
  122. // HttpRequest::update(). This method does the necessary dispatching.
  123. //
  124. // Threading: called by consumer thread.
  125. //
  126. virtual void visitNotifier(HttpRequest*);
  127. // Cancels the operation whether queued or active. The final status of the
  128. // request becomes cancelled (an error) and that will be delivered to
  129. // caller via notification scheme.
  130. //
  131. // Threading: called by worker thread.
  132. //
  133. virtual HttpStatus cancel();
  134. // Retrieves a unique handle for this operation.
  135. HttpHandle getHandle();
  136. template<class OPT>
  137. static std::shared_ptr<OPT> fromHandle(HttpHandle handle)
  138. {
  139. ptr_t ptr = findByHandle(handle);
  140. if (!ptr)
  141. {
  142. return std::shared_ptr<OPT>();
  143. }
  144. return std::dynamic_pointer_cast<OPT>(ptr);
  145. }
  146. protected:
  147. // Delivers request to reply queue on completion. After this call, worker
  148. // thread no longer accesses the object and it is owned by the reply queue.
  149. //
  150. // Threading: called by worker thread.
  151. //
  152. void addAsReply();
  153. static ptr_t findByHandle(HttpHandle handle);
  154. private:
  155. HttpHandle createHandle();
  156. void destroyHandle();
  157. public:
  158. // Request Data
  159. HttpRequest::policy_t mReqPolicy;
  160. // Reply Data
  161. HttpStatus mStatus;
  162. // Tracing, debug and metrics
  163. HttpTime mMetricCreated;
  164. long mTracing;
  165. protected:
  166. HttpReplyQueuePtr_t mReplyQueue;
  167. HttpHandler::ptr_t mUserHandler;
  168. private:
  169. HttpHandle mMyHandle;
  170. typedef std::map<HttpHandle, wptr_t> handleMap_t;
  171. static handleMap_t sHandleMap;
  172. static LLCoreInt::HttpMutex sOpMutex;
  173. };
  174. // HttpOpStop requests the servicing thread to shutdown operations, cease
  175. // pulling requests from the request queue and release shared resources
  176. // (particularly those shared via reference count). The servicing thread will
  177. // then exit. The underlying thread object remains so that another thread can
  178. // join on the servicing thread prior to final cleanup. The request *does*
  179. // generate a reply on the response queue, if requested.
  180. class HttpOpStop final : public HttpOperation
  181. {
  182. public:
  183. HttpOpStop();
  184. HttpOpStop(const HttpOpStop&) = delete;
  185. void operator=(const HttpOpStop&) = delete;
  186. public:
  187. void stageFromRequest(HttpService*) override;
  188. };
  189. // HttpOpNull is a do-nothing operation used for testing via a basic loopback
  190. // pattern. It is executed immediately by the servicing thread which bounces a
  191. // reply back to the caller without any further delay.
  192. class HttpOpNull final : public HttpOperation
  193. {
  194. public:
  195. HttpOpNull();
  196. private:
  197. HttpOpNull(const HttpOpNull&) = delete;
  198. void operator=(const HttpOpNull&) = delete;
  199. public:
  200. void stageFromRequest(HttpService*) override;
  201. };
  202. } // End namespace LLCore
  203. #endif // _LLCORE_HTTP_OPERATION_H_