blob: 0ac3028ad752f6c15f6344a4171254a6d01ae370 [file] [log] [blame]
Roger Meier2be7f242012-05-10 09:01:45 +00001/*
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 Meier2b1a5282012-05-11 10:12:39 +000019#include "EventLog.h"
Roger Meier2be7f242012-05-10 09:01:45 +000020
21#include <stdarg.h>
22
23using namespace std;
24using namespace apache::thrift::concurrency;
25
26namespace {
27
28void 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}
39
40}
41
42namespace apache { namespace thrift { namespace test {
43
44uint32_t EventLog::nextId_ = 0;
45
46#define EVENT_TYPE(value) EventType EventLog::value = #value
47EVENT_TYPE(ET_LOG_END);
48EVENT_TYPE(ET_CONN_CREATED);
49EVENT_TYPE(ET_CONN_DESTROYED);
50EVENT_TYPE(ET_CALL_STARTED);
51EVENT_TYPE(ET_CALL_FINISHED);
52EVENT_TYPE(ET_PROCESS);
53EVENT_TYPE(ET_PRE_READ);
54EVENT_TYPE(ET_POST_READ);
55EVENT_TYPE(ET_PRE_WRITE);
56EVENT_TYPE(ET_POST_WRITE);
57EVENT_TYPE(ET_ASYNC_COMPLETE);
58EVENT_TYPE(ET_HANDLER_ERROR);
59
60EVENT_TYPE(ET_CALL_INCREMENT_GENERATION);
61EVENT_TYPE(ET_CALL_GET_GENERATION);
62EVENT_TYPE(ET_CALL_ADD_STRING);
63EVENT_TYPE(ET_CALL_GET_STRINGS);
64EVENT_TYPE(ET_CALL_GET_DATA_WAIT);
65EVENT_TYPE(ET_CALL_ONEWAY_WAIT);
66EVENT_TYPE(ET_CALL_EXCEPTION_WAIT);
67EVENT_TYPE(ET_CALL_UNEXPECTED_EXCEPTION_WAIT);
68EVENT_TYPE(ET_CALL_SET_VALUE);
69EVENT_TYPE(ET_CALL_GET_VALUE);
70EVENT_TYPE(ET_WAIT_RETURN);
71
72EventLog::EventLog() {
73 id_ = nextId_++;
74 debug("New log: %d", id_);
75}
76
77void EventLog::append(EventType type, uint32_t connectionId, uint32_t callId,
78 const string& message) {
79 Synchronized s(monitor_);
80 debug("%d <-- %u, %u, %s \"%s\"", id_, connectionId, callId, type,
81 message.c_str());
82
83 Event e(type, connectionId, callId, message);
84 events_.push_back(e);
85
86 monitor_.notify();
87}
88
89Event EventLog::waitForEvent(int64_t timeout) {
90 Synchronized s(monitor_);
91
92 try {
93 while (events_.empty()) {
94 monitor_.wait(timeout);
95 }
96 } catch (TimedOutException ex) {
97 return Event(ET_LOG_END, 0, 0, "");
98 }
99
100 Event event = events_.front();
101 events_.pop_front();
102 return event;
103}
104
105Event EventLog::waitForConnEvent(uint32_t connId, int64_t timeout) {
106 Synchronized s(monitor_);
107
108 EventList::iterator it = events_.begin();
109 while (true) {
110 try {
111 // TODO: it would be nicer to honor timeout for the duration of this
112 // call, rather than restarting it for each call to wait(). It shouldn't
113 // be a big problem in practice, though.
114 while (it == events_.end()) {
115 monitor_.wait(timeout);
116 }
117 } catch (TimedOutException ex) {
118 return Event(ET_LOG_END, 0, 0, "");
119 }
120
121 if (it->connectionId == connId) {
122 Event event = *it;
123 events_.erase(it);
124 return event;
125 }
126 }
127}
128
129}}} // apache::thrift::test