diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/lleventpoll.cpp | 255 |
1 files changed, 130 insertions, 125 deletions
diff --git a/linden/indra/newview/lleventpoll.cpp b/linden/indra/newview/lleventpoll.cpp index 5407ee2..9c5a19d 100644 --- a/linden/indra/newview/lleventpoll.cpp +++ b/linden/indra/newview/lleventpoll.cpp | |||
@@ -1,9 +1,10 @@ | |||
1 | /** | 1 | /** |
2 | * @file lleventpoll.cpp | 2 | * @file lleventpoll.cpp |
3 | * @brief Implementation of the LLEventPoll class. | 3 | * @brief Implementation of the LLEventPoll class. |
4 | * | 4 | * |
5 | * Copyright (c) 2006-2007, Linden Research, Inc. | 5 | * Copyright (c) 2006-2007, Linden Research, Inc. |
6 | * | 6 | * |
7 | * Second Life Viewer Source Code | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | 8 | * 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 | * 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 | * ("GPL"), unless you have obtained a separate licensing agreement |
@@ -27,156 +28,160 @@ | |||
27 | 28 | ||
28 | #include "llviewerprecompiledheaders.h" | 29 | #include "llviewerprecompiledheaders.h" |
29 | 30 | ||
31 | #include "llagent.h" | ||
30 | #include "lleventpoll.h" | 32 | #include "lleventpoll.h" |
31 | 33 | ||
32 | #include "llhttpclient.h" | 34 | #include "llhttpclient.h" |
33 | #include "llhttpnode.h" | ||
34 | #include "llsdserialize.h" | 35 | #include "llsdserialize.h" |
36 | #include "llviewerregion.h" | ||
37 | #include "message.h" | ||
35 | 38 | ||
39 | class LLEventPoll::Impl : LLHTTPClient::Responder | ||
40 | { | ||
41 | public: | ||
42 | static Impl& start(const std::string& pollURL); | ||
43 | void stop(); | ||
44 | |||
45 | private: | ||
46 | Impl(const std::string& pollURL); | ||
47 | ~Impl(); | ||
48 | |||
49 | void makeRequest(); | ||
50 | void handleMessage(const LLSD& content); | ||
51 | virtual void error(U32 status, const std::string& reason); | ||
52 | virtual void result(const LLSD& content); | ||
36 | 53 | ||
54 | private: | ||
55 | typedef LLHTTPClient::ResponderPtr Ptr; | ||
37 | 56 | ||
38 | class LLEventPoll::Impl : LLHTTPClient::Responder | 57 | Ptr mPtr; |
58 | bool mDone; | ||
59 | |||
60 | std::string mPollURL; | ||
61 | std::string mSender; | ||
62 | |||
63 | LLSD mAcknowledge; | ||
64 | |||
65 | // these are only here for debugging so we can see which poller is which | ||
66 | static int sCount; | ||
67 | int mCount; | ||
68 | }; | ||
69 | |||
70 | //static | ||
71 | LLEventPoll::Impl& LLEventPoll::Impl::start( | ||
72 | const std::string& pollURL) | ||
39 | { | 73 | { |
40 | public: | 74 | Impl* i = new Impl(pollURL); |
41 | static Impl& start( | 75 | llinfos << "LLEventPoll::Impl::start <" << i->mCount << "> " |
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; | 76 | << pollURL << llendl; |
47 | return *i; | 77 | return *i; |
48 | } | 78 | } |
49 | 79 | ||
50 | void stop() | 80 | void LLEventPoll::Impl::stop() |
81 | { | ||
82 | llinfos << "LLEventPoll::Impl::stop <" << mCount << "> " | ||
83 | << mPollURL << llendl; | ||
84 | // there should be a way to stop a LLHTTPClient request in progress | ||
85 | mDone = true; | ||
86 | mPtr = NULL; | ||
87 | } | ||
88 | |||
89 | int LLEventPoll::Impl::sCount = 0; | ||
90 | |||
91 | LLEventPoll::Impl::Impl(const std::string& pollURL) | ||
92 | : mPtr(NULL), mDone(false), | ||
93 | mPollURL(pollURL), | ||
94 | mCount(++sCount) | ||
95 | { | ||
96 | mPtr = this; | ||
97 | //extract host and port of simulator to set as sender | ||
98 | LLViewerRegion *regionp = gAgent.getRegion(); | ||
99 | if (!regionp) | ||
51 | { | 100 | { |
52 | lldebugs << "LLEventPoll::Impl::stop <" << mCount << "> " | 101 | llerrs << "LLEventPoll initialized before region is added." << llendl; |
53 | << mPollURL << llendl; | ||
54 | // there should be a way to stop a LLHTTPClient request in progress | ||
55 | mDone = true; | ||
56 | mPtr = NULL; | ||
57 | } | 102 | } |
103 | mSender = regionp->getHost().getIPandPort(); | ||
104 | llinfos << "LLEventPoll initialized with sender " << mSender << llendl; | ||
105 | makeRequest(); | ||
106 | } | ||
107 | |||
108 | LLEventPoll::Impl::~Impl() | ||
109 | { | ||
110 | lldebugs << "LLEventPoll::Impl::~Impl <" << mCount << "> " | ||
111 | << mPollURL << llendl; | ||
112 | } | ||
113 | |||
114 | void LLEventPoll::Impl::makeRequest() | ||
115 | { | ||
116 | LLSD request; | ||
117 | request["ack"] = mAcknowledge; | ||
118 | request["done"] = mDone; | ||
58 | 119 | ||
59 | private: | 120 | lldebugs << "LLEventPoll::Impl::makeRequest <" << mCount << "> ack = " |
60 | Impl(const std::string& pollURL, const LLHTTPNode& treeRoot) | 121 | << LLSDXMLStreamer(mAcknowledge) << llendl; |
61 | : mPtr(NULL), mDone(false), | 122 | LLHTTPClient::post(mPollURL, request, mPtr); |
62 | mPollURL(pollURL), mTreeRoot(treeRoot), | 123 | } |
63 | mCount(++sCount) | 124 | |
64 | { | 125 | void LLEventPoll::Impl::handleMessage(const LLSD& content) |
65 | mPtr = this; | 126 | { |
66 | makeRequest(); | 127 | std::string msg_name = content["message"]; |
67 | } | 128 | LLSD message; |
68 | 129 | message["sender"] = mSender; | |
69 | ~Impl() | 130 | message["body"] = content["body"]; |
70 | { | 131 | LLMessageSystem::dispatch(msg_name, message); |
71 | lldebugs << "LLEventPoll::Impl::~Impl <" << mCount << "> " | 132 | } |
72 | << mPollURL << llendl; | ||
73 | } | ||
74 | 133 | ||
134 | //virtual | ||
135 | void LLEventPoll::Impl::error(U32 status, const std::string& reason) | ||
136 | { | ||
137 | if (mDone) return; | ||
75 | 138 | ||
76 | void makeRequest() | 139 | if(status != 499) |
77 | { | 140 | { |
78 | LLSD request; | 141 | llwarns << "LLEventPoll::Impl::error: <" << mCount << "> got " |
79 | request["ack"] = mAcknowledge; | 142 | << status << ": " << reason |
80 | request["done"] = mDone; | 143 | << (mDone ? " -- done" : "") << llendl; |
81 | 144 | stop(); | |
82 | lldebugs << "LLEventPoll::Impl::makeRequest <" << mCount << "> ack = " | 145 | return; |
83 | << LLSDXMLStreamer(mAcknowledge) << llendl; | ||
84 | LLHTTPClient::post(mPollURL, request, mPtr); | ||
85 | } | 146 | } |
147 | |||
148 | makeRequest(); | ||
149 | } | ||
150 | |||
151 | //virtual | ||
152 | void LLEventPoll::Impl::result(const LLSD& content) | ||
153 | { | ||
154 | lldebugs << "LLEventPoll::Impl::result <" << mCount << ">" | ||
155 | << (mDone ? " -- done" : "") << llendl; | ||
86 | 156 | ||
87 | void handleMessage(const LLSD& content) | 157 | if (mDone) return; |
88 | { | 158 | |
89 | std::string message = content["message"]; | 159 | mAcknowledge = content["id"]; |
90 | if (message.empty()) | 160 | LLSD events = content["events"]; |
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 | 161 | ||
114 | virtual void error(U32 status, const std::string& reason) | 162 | if(mAcknowledge.isUndefined()) |
115 | { | 163 | { |
116 | lldebugs << "LLEventPoll::Impl::error <" << mCount << "> got " | 164 | llwarns << "LLEventPoll::Impl: id undefined" << llendl; |
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 | } | 165 | } |
131 | 166 | ||
167 | llinfos << "LLEventPoll::Impl::completed <" << mCount << "> " << events.size() << "events (id " | ||
168 | << LLSDXMLStreamer(mAcknowledge) << ")" << llendl; | ||
132 | 169 | ||
133 | virtual void result(const LLSD& content) | 170 | LLSD::array_const_iterator i = events.beginArray(); |
171 | LLSD::array_const_iterator end = events.endArray(); | ||
172 | for (; i != end; ++i) | ||
134 | { | 173 | { |
135 | lldebugs << "LLEventPoll::Impl::result <" << mCount << ">" | 174 | if (i->has("message")) |
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 | { | 175 | { |
150 | if (i->has("message")) | 176 | handleMessage(*i); |
151 | { | ||
152 | handleMessage(*i); | ||
153 | } | ||
154 | } | 177 | } |
155 | |||
156 | makeRequest(); | ||
157 | } | 178 | } |
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 | 179 | ||
168 | LLSD mAcknowledge; | 180 | makeRequest(); |
169 | 181 | } | |
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 | 182 | ||
178 | LLEventPoll::LLEventPoll(const std::string& pollURL, const LLHTTPNode& treeRoot) | 183 | LLEventPoll::LLEventPoll(const std::string& pollURL) |
179 | : impl(Impl::start(pollURL, treeRoot)) | 184 | : impl(Impl::start(pollURL)) |
180 | { } | 185 | { } |
181 | 186 | ||
182 | LLEventPoll::~LLEventPoll() | 187 | LLEventPoll::~LLEventPoll() |