diff options
Diffstat (limited to 'linden/indra/newview/lleventpoll.cpp')
-rw-r--r-- | linden/indra/newview/lleventpoll.cpp | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/linden/indra/newview/lleventpoll.cpp b/linden/indra/newview/lleventpoll.cpp new file mode 100644 index 0000000..ece0958 --- /dev/null +++ b/linden/indra/newview/lleventpoll.cpp | |||
@@ -0,0 +1,185 @@ | |||
1 | /** | ||
2 | * @file lleventpoll.cpp | ||
3 | * @brief Implementation of the LLEventPoll class. | ||
4 | * | ||
5 | * Copyright (c) 2006-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #include "llviewerprecompiledheaders.h" | ||
29 | |||
30 | #include "lleventpoll.h" | ||
31 | |||
32 | #include "llhttpclient.h" | ||
33 | #include "llhttpnode.h" | ||
34 | #include "llsdserialize.h" | ||
35 | |||
36 | |||
37 | |||
38 | class LLEventPoll::Impl : LLHTTPClient::Responder | ||
39 | { | ||
40 | public: | ||
41 | static Impl& start( | ||
42 | const std::string& pollURL, const LLHTTPNode& treeRoot) | ||
43 | { | ||
44 | Impl* i = new Impl(pollURL, treeRoot); | ||
45 | llinfos << "LLEventPoll::Impl::start <" << i->mCount << "> " | ||
46 | << pollURL << llendl; | ||
47 | return *i; | ||
48 | } | ||
49 | |||
50 | void stop() | ||
51 | { | ||
52 | llinfos << "LLEventPoll::Impl::stop <" << mCount << "> " | ||
53 | << mPollURL << llendl; | ||
54 | // there should be a way to stop a LLHTTPClient request in progress | ||
55 | mDone = true; | ||
56 | mPtr = NULL; | ||
57 | } | ||
58 | |||
59 | private: | ||
60 | Impl(const std::string& pollURL, const LLHTTPNode& treeRoot) | ||
61 | : mPtr(NULL), mDone(false), | ||
62 | mPollURL(pollURL), mTreeRoot(treeRoot), | ||
63 | mCount(++sCount) | ||
64 | { | ||
65 | mPtr = this; | ||
66 | makeRequest(); | ||
67 | } | ||
68 | |||
69 | ~Impl() | ||
70 | { | ||
71 | lldebugs << "LLEventPoll::Impl::~Impl <" << mCount << "> " | ||
72 | << mPollURL << llendl; | ||
73 | } | ||
74 | |||
75 | |||
76 | void makeRequest() | ||
77 | { | ||
78 | LLSD request; | ||
79 | request["ack"] = mAcknowledge; | ||
80 | request["done"] = mDone; | ||
81 | |||
82 | lldebugs << "LLEventPoll::Impl::makeRequest <" << mCount << "> ack = " | ||
83 | << LLSDXMLStreamer(mAcknowledge) << llendl; | ||
84 | LLHTTPClient::post(mPollURL, request, mPtr); | ||
85 | } | ||
86 | |||
87 | void handleMessage(const LLSD& content) | ||
88 | { | ||
89 | std::string message = content["message"]; | ||
90 | if (message.empty()) | ||
91 | { | ||
92 | llwarns << "LLEventPoll::Impl::handleMessage <" << mCount | ||
93 | << "> empty message name" << llendl; | ||
94 | return; | ||
95 | } | ||
96 | |||
97 | std::string path = "/message/" + message; | ||
98 | |||
99 | LLSD context; | ||
100 | const LLHTTPNode* handler = mTreeRoot.traverse(path, context); | ||
101 | if (!handler) | ||
102 | { | ||
103 | llwarns << "LLEventPoll::Impl::handleMessage <" << mCount | ||
104 | << "> no handler for " << path << llendl; | ||
105 | return; | ||
106 | } | ||
107 | LLPointer<LLSimpleResponse> responsep = LLSimpleResponse::create(); | ||
108 | handler->post((LLHTTPNode::ResponsePtr)responsep, context, content["body"]); | ||
109 | |||
110 | lldebugs << "LLEventPoll::Impl::handleMessage handled <" << mCount << "> " | ||
111 | << message << ": " << *responsep << llendl; | ||
112 | } | ||
113 | |||
114 | virtual void error(U32 status, const std::string& reason) | ||
115 | { | ||
116 | lldebugs << "LLEventPoll::Impl::error <" << mCount << "> got " | ||
117 | << status << ": " << reason | ||
118 | << (mDone ? " -- done" : "") << llendl; | ||
119 | |||
120 | if (mDone) return; | ||
121 | |||
122 | if (status == 404) | ||
123 | { | ||
124 | // the capability has been revoked | ||
125 | stop(); | ||
126 | return; | ||
127 | } | ||
128 | |||
129 | makeRequest(); | ||
130 | } | ||
131 | |||
132 | |||
133 | virtual void result(const LLSD& content) | ||
134 | { | ||
135 | lldebugs << "LLEventPoll::Impl::result <" << mCount << ">" | ||
136 | << (mDone ? " -- done" : "") << llendl; | ||
137 | |||
138 | if (mDone) return; | ||
139 | |||
140 | mAcknowledge = content["id"]; | ||
141 | LLSD events = content["events"]; | ||
142 | |||
143 | lldebugs << "LLEventPoll::Impl::completed <" << mCount << "> ack = " | ||
144 | << LLSDXMLStreamer(mAcknowledge) << llendl; | ||
145 | |||
146 | LLSD::array_const_iterator i = events.beginArray(); | ||
147 | LLSD::array_const_iterator end = events.endArray(); | ||
148 | for (; i != end; ++i) | ||
149 | { | ||
150 | if (i->has("message")) | ||
151 | { | ||
152 | handleMessage(*i); | ||
153 | } | ||
154 | } | ||
155 | |||
156 | makeRequest(); | ||
157 | } | ||
158 | |||
159 | private: | ||
160 | typedef LLHTTPClient::ResponderPtr Ptr; | ||
161 | |||
162 | Ptr mPtr; | ||
163 | bool mDone; | ||
164 | |||
165 | std::string mPollURL; | ||
166 | const LLHTTPNode& mTreeRoot; | ||
167 | |||
168 | LLSD mAcknowledge; | ||
169 | |||
170 | // these are only here for debugging so we can see which poller is which | ||
171 | static int sCount; | ||
172 | int mCount; | ||
173 | }; | ||
174 | |||
175 | int LLEventPoll::Impl::sCount = 0; | ||
176 | |||
177 | |||
178 | LLEventPoll::LLEventPoll(const std::string& pollURL, const LLHTTPNode& treeRoot) | ||
179 | : impl(Impl::start(pollURL, treeRoot)) | ||
180 | { } | ||
181 | |||
182 | LLEventPoll::~LLEventPoll() | ||
183 | { | ||
184 | impl.stop(); | ||
185 | } | ||