PollServiceWorkerThread.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSimulator Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Collections;
  29. using System.Collections.Generic;
  30. using System.IO;
  31. using System.Text;
  32. using HttpServer;
  33. using OpenMetaverse;
  34. using System.Reflection;
  35. using log4net;
  36. using OpenSim.Framework.Monitoring;
  37. namespace OpenSim.Framework.Servers.HttpServer
  38. {
  39. public delegate void ReQueuePollServiceItem(PollServiceHttpRequest req);
  40. public class PollServiceWorkerThread
  41. {
  42. private static readonly ILog m_log =
  43. LogManager.GetLogger(
  44. MethodBase.GetCurrentMethod().DeclaringType);
  45. public event ReQueuePollServiceItem ReQueue;
  46. private readonly BaseHttpServer m_server;
  47. private BlockingQueue<PollServiceHttpRequest> m_request;
  48. private bool m_running = true;
  49. private int m_timeout = 250;
  50. public PollServiceWorkerThread(BaseHttpServer pSrv, int pTimeout)
  51. {
  52. m_request = new BlockingQueue<PollServiceHttpRequest>();
  53. m_server = pSrv;
  54. m_timeout = pTimeout;
  55. }
  56. public void ThreadStart()
  57. {
  58. Run();
  59. }
  60. public void Run()
  61. {
  62. while (m_running)
  63. {
  64. PollServiceHttpRequest req = m_request.Dequeue();
  65. Watchdog.UpdateThread();
  66. try
  67. {
  68. if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id))
  69. {
  70. StreamReader str;
  71. try
  72. {
  73. str = new StreamReader(req.Request.Body);
  74. }
  75. catch (System.ArgumentException)
  76. {
  77. // Stream was not readable means a child agent
  78. // was closed due to logout, leaving the
  79. // Event Queue request orphaned.
  80. continue;
  81. }
  82. Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd());
  83. DoHTTPGruntWork(m_server, req, responsedata);
  84. }
  85. else
  86. {
  87. if ((Environment.TickCount - req.RequestTime) > m_timeout)
  88. {
  89. DoHTTPGruntWork(
  90. m_server,
  91. req,
  92. req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
  93. }
  94. else
  95. {
  96. ReQueuePollServiceItem reQueueItem = ReQueue;
  97. if (reQueueItem != null)
  98. reQueueItem(req);
  99. }
  100. }
  101. }
  102. catch (Exception e)
  103. {
  104. m_log.ErrorFormat("Exception in poll service thread: " + e.ToString());
  105. }
  106. }
  107. }
  108. internal void Enqueue(PollServiceHttpRequest pPollServiceHttpRequest)
  109. {
  110. m_request.Enqueue(pPollServiceHttpRequest);
  111. }
  112. /// <summary>
  113. /// FIXME: This should be part of BaseHttpServer
  114. /// </summary>
  115. internal static void DoHTTPGruntWork(BaseHttpServer server, PollServiceHttpRequest req, Hashtable responsedata)
  116. {
  117. OSHttpResponse response
  118. = new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext);
  119. byte[] buffer = server.DoHTTPGruntWork(responsedata, response);
  120. response.SendChunked = false;
  121. response.ContentLength64 = buffer.Length;
  122. response.ContentEncoding = Encoding.UTF8;
  123. try
  124. {
  125. response.OutputStream.Write(buffer, 0, buffer.Length);
  126. }
  127. catch (Exception ex)
  128. {
  129. m_log.Warn(string.Format("[POLL SERVICE WORKER THREAD]: Error ", ex));
  130. }
  131. finally
  132. {
  133. //response.OutputStream.Close();
  134. try
  135. {
  136. response.OutputStream.Flush();
  137. response.Send();
  138. //if (!response.KeepAlive && response.ReuseContext)
  139. // response.FreeContext();
  140. }
  141. catch (Exception e)
  142. {
  143. m_log.Warn(String.Format("[POLL SERVICE WORKER THREAD]: Error ", e));
  144. }
  145. }
  146. }
  147. }
  148. }