| Roger Meier | 2be7f24 | 2012-05-10 09:01:45 +0000 | [diff] [blame] | 1 | /* | 
 | 2 |  * Licensed to the Apache Software Foundation (ASF) under one | 
 | 3 |  * or more contributor license agreements. See the NOTICE file | 
 | 4 |  * distributed with this work for additional information | 
 | 5 |  * regarding copyright ownership. The ASF licenses this file | 
 | 6 |  * to you under the Apache License, Version 2.0 (the | 
 | 7 |  * "License"); you may not use this file except in compliance | 
 | 8 |  * with the License. You may obtain a copy of the License at | 
 | 9 |  * | 
 | 10 |  *   http://www.apache.org/licenses/LICENSE-2.0 | 
 | 11 |  * | 
 | 12 |  * Unless required by applicable law or agreed to in writing, | 
 | 13 |  * software distributed under the License is distributed on an | 
 | 14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
 | 15 |  * KIND, either express or implied. See the License for the | 
 | 16 |  * specific language governing permissions and limitations | 
 | 17 |  * under the License. | 
 | 18 |  */ | 
| Roger Meier | 2b1a528 | 2012-05-11 10:12:39 +0000 | [diff] [blame] | 19 | #include "EventLog.h" | 
| Roger Meier | 2be7f24 | 2012-05-10 09:01:45 +0000 | [diff] [blame] | 20 |  | 
 | 21 | #include <stdarg.h> | 
 | 22 |  | 
 | 23 | using namespace std; | 
 | 24 | using namespace apache::thrift::concurrency; | 
 | 25 |  | 
 | 26 | namespace { | 
 | 27 |  | 
 | 28 | void debug(const char* fmt, ...) { | 
 | 29 |   // Comment out this return to enable debug logs from the test code. | 
 | 30 |   return; | 
 | 31 |  | 
 | 32 |   va_list ap; | 
 | 33 |   va_start(ap, fmt); | 
 | 34 |   vfprintf(stderr, fmt, ap); | 
 | 35 |   va_end(ap); | 
 | 36 |  | 
 | 37 |   fprintf(stderr, "\n"); | 
 | 38 | } | 
| Roger Meier | 2be7f24 | 2012-05-10 09:01:45 +0000 | [diff] [blame] | 39 | } | 
 | 40 |  | 
| Konrad Grochowski | 16a23a6 | 2014-11-13 15:33:38 +0100 | [diff] [blame] | 41 | namespace apache { | 
 | 42 | namespace thrift { | 
 | 43 | namespace test { | 
| Roger Meier | 2be7f24 | 2012-05-10 09:01:45 +0000 | [diff] [blame] | 44 |  | 
 | 45 | uint32_t EventLog::nextId_ = 0; | 
 | 46 |  | 
 | 47 | #define EVENT_TYPE(value) EventType EventLog::value = #value | 
 | 48 | EVENT_TYPE(ET_LOG_END); | 
 | 49 | EVENT_TYPE(ET_CONN_CREATED); | 
 | 50 | EVENT_TYPE(ET_CONN_DESTROYED); | 
 | 51 | EVENT_TYPE(ET_CALL_STARTED); | 
 | 52 | EVENT_TYPE(ET_CALL_FINISHED); | 
 | 53 | EVENT_TYPE(ET_PROCESS); | 
 | 54 | EVENT_TYPE(ET_PRE_READ); | 
 | 55 | EVENT_TYPE(ET_POST_READ); | 
 | 56 | EVENT_TYPE(ET_PRE_WRITE); | 
 | 57 | EVENT_TYPE(ET_POST_WRITE); | 
 | 58 | EVENT_TYPE(ET_ASYNC_COMPLETE); | 
 | 59 | EVENT_TYPE(ET_HANDLER_ERROR); | 
 | 60 |  | 
 | 61 | EVENT_TYPE(ET_CALL_INCREMENT_GENERATION); | 
 | 62 | EVENT_TYPE(ET_CALL_GET_GENERATION); | 
 | 63 | EVENT_TYPE(ET_CALL_ADD_STRING); | 
 | 64 | EVENT_TYPE(ET_CALL_GET_STRINGS); | 
 | 65 | EVENT_TYPE(ET_CALL_GET_DATA_WAIT); | 
 | 66 | EVENT_TYPE(ET_CALL_ONEWAY_WAIT); | 
 | 67 | EVENT_TYPE(ET_CALL_EXCEPTION_WAIT); | 
 | 68 | EVENT_TYPE(ET_CALL_UNEXPECTED_EXCEPTION_WAIT); | 
 | 69 | EVENT_TYPE(ET_CALL_SET_VALUE); | 
 | 70 | EVENT_TYPE(ET_CALL_GET_VALUE); | 
 | 71 | EVENT_TYPE(ET_WAIT_RETURN); | 
 | 72 |  | 
 | 73 | EventLog::EventLog() { | 
 | 74 |   id_ = nextId_++; | 
 | 75 |   debug("New log: %d", id_); | 
 | 76 | } | 
 | 77 |  | 
| Konrad Grochowski | 16a23a6 | 2014-11-13 15:33:38 +0100 | [diff] [blame] | 78 | void EventLog::append(EventType type, | 
 | 79 |                       uint32_t connectionId, | 
 | 80 |                       uint32_t callId, | 
| Roger Meier | 2be7f24 | 2012-05-10 09:01:45 +0000 | [diff] [blame] | 81 |                       const string& message) { | 
 | 82 |   Synchronized s(monitor_); | 
| Konrad Grochowski | 16a23a6 | 2014-11-13 15:33:38 +0100 | [diff] [blame] | 83 |   debug("%d <-- %u, %u, %s \"%s\"", id_, connectionId, callId, type, message.c_str()); | 
| Roger Meier | 2be7f24 | 2012-05-10 09:01:45 +0000 | [diff] [blame] | 84 |  | 
 | 85 |   Event e(type, connectionId, callId, message); | 
 | 86 |   events_.push_back(e); | 
 | 87 |  | 
 | 88 |   monitor_.notify(); | 
 | 89 | } | 
 | 90 |  | 
 | 91 | Event EventLog::waitForEvent(int64_t timeout) { | 
 | 92 |   Synchronized s(monitor_); | 
 | 93 |  | 
 | 94 |   try { | 
 | 95 |     while (events_.empty()) { | 
 | 96 |       monitor_.wait(timeout); | 
 | 97 |     } | 
 | 98 |   } catch (TimedOutException ex) { | 
 | 99 |     return Event(ET_LOG_END, 0, 0, ""); | 
 | 100 |   } | 
 | 101 |  | 
 | 102 |   Event event = events_.front(); | 
 | 103 |   events_.pop_front(); | 
 | 104 |   return event; | 
 | 105 | } | 
 | 106 |  | 
 | 107 | Event EventLog::waitForConnEvent(uint32_t connId, int64_t timeout) { | 
 | 108 |   Synchronized s(monitor_); | 
 | 109 |  | 
 | 110 |   EventList::iterator it = events_.begin(); | 
 | 111 |   while (true) { | 
 | 112 |     try { | 
 | 113 |       // TODO: it would be nicer to honor timeout for the duration of this | 
 | 114 |       // call, rather than restarting it for each call to wait().  It shouldn't | 
 | 115 |       // be a big problem in practice, though. | 
 | 116 |       while (it == events_.end()) { | 
 | 117 |         monitor_.wait(timeout); | 
 | 118 |       } | 
 | 119 |     } catch (TimedOutException ex) { | 
 | 120 |       return Event(ET_LOG_END, 0, 0, ""); | 
 | 121 |     } | 
 | 122 |  | 
 | 123 |     if (it->connectionId == connId) { | 
 | 124 |       Event event = *it; | 
 | 125 |       events_.erase(it); | 
 | 126 |       return event; | 
 | 127 |     } | 
 | 128 |   } | 
 | 129 | } | 
| Konrad Grochowski | 16a23a6 | 2014-11-13 15:33:38 +0100 | [diff] [blame] | 130 | } | 
 | 131 | } | 
 | 132 | } // apache::thrift::test |