aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/lleventpoll.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/lleventpoll.cpp')
-rw-r--r--linden/indra/newview/lleventpoll.cpp185
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
38class LLEventPoll::Impl : LLHTTPClient::Responder
39{
40public:
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
59private:
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
159private:
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
175int LLEventPoll::Impl::sCount = 0;
176
177
178LLEventPoll::LLEventPoll(const std::string& pollURL, const LLHTTPNode& treeRoot)
179 : impl(Impl::start(pollURL, treeRoot))
180 { }
181
182LLEventPoll::~LLEventPoll()
183{
184 impl.stop();
185}