]> git.proxmox.com Git - ceph.git/blame - ceph/src/jaegertracing/thrift/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.cpp
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / jaegertracing / thrift / lib / cpp / src / thrift / windows / OverlappedSubmissionThread.cpp
CommitLineData
f67539c2
TL
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*/
19
20#include <thrift/windows/OverlappedSubmissionThread.h>
21#include <thrift/transport/TTransportException.h>
22#include <boost/noncopyable.hpp>
23#include <boost/scope_exit.hpp>
24#include <process.h>
25
26namespace apache {
27namespace thrift {
28namespace transport {
29
30TOverlappedWorkItem::TOverlappedWorkItem()
31 : SLIST_ENTRY(),
32 action(UNKNOWN),
33 h(INVALID_HANDLE_VALUE),
34 buffer(NULL),
35 buffer_len(0),
36 overlap(),
37 last_error(0),
38 success(TRUE) {
39}
40
41void TOverlappedWorkItem::reset(uint8_t* buf, uint32_t len, HANDLE event) {
42 memset(&overlap, 0, sizeof(overlap));
43 overlap.hEvent = event;
44 buffer = buf;
45 buffer_len = len;
46 last_error = 0;
47 success = FALSE;
48}
49
50uint32_t TOverlappedWorkItem::overlappedResults(bool signal_failure) {
51 DWORD bytes = 0;
52 BOOL result = ::GetOverlappedResult(h, &overlap, &bytes, TRUE);
53 if (signal_failure && !result) // get overlapped error case
54 {
55 GlobalOutput.perror("TPipe ::GetOverlappedResult errored GLE=", ::GetLastError());
56 throw TTransportException(TTransportException::UNKNOWN, "TPipe: GetOverlappedResult failed");
57 }
58 return bytes;
59}
60
61bool TOverlappedWorkItem::process() {
62 BOOST_SCOPE_EXIT((&doneSubmittingEvent)) { SetEvent(doneSubmittingEvent.h); }
63 BOOST_SCOPE_EXIT_END
64
65 switch (action) {
66 case (CONNECT):
67 success = ::ConnectNamedPipe(h, &overlap);
68 if (success == FALSE)
69 last_error = ::GetLastError();
70 return true;
71 case (READ):
72 success = ::ReadFile(h, buffer, buffer_len, NULL, &overlap);
73 if (success == FALSE)
74 last_error = ::GetLastError();
75 return true;
76 case (CANCELIO):
77 success = ::CancelIo(h);
78 if (success == FALSE)
79 last_error = ::GetLastError();
80 return true;
81 case (STOP):
82 default:
83 return false;
84 }
85}
86
87void TOverlappedSubmissionThread::addWorkItem(TOverlappedWorkItem* item) {
88 InterlockedPushEntrySList(&workList_, item);
89 SetEvent(workAvailableEvent_.h);
90 WaitForSingleObject(item->doneSubmittingEvent.h, INFINITE);
91}
92
93TOverlappedSubmissionThread* TOverlappedSubmissionThread::acquire_instance() {
94 TAutoCrit lock(instanceGuard_);
95 if (instance_ == NULL) {
96 assert(instanceRefCount_ == 0);
97 instance_ = new TOverlappedSubmissionThread;
98 }
99 ++instanceRefCount_;
100 return instance_;
101}
102void TOverlappedSubmissionThread::release_instance() {
103 TAutoCrit lock(instanceGuard_);
104 if (--instanceRefCount_ == 0) {
105 delete instance_;
106 instance_ = NULL;
107 }
108}
109
110TOverlappedSubmissionThread::TOverlappedSubmissionThread() {
111 stopItem_.action = TOverlappedWorkItem::STOP;
112
113 InitializeSListHead(&workList_);
114 thread_ = (HANDLE)_beginthreadex(NULL, 0, thread_proc, this, 0, NULL);
115 if (thread_ == 0) {
116 GlobalOutput.perror("TOverlappedSubmissionThread unable to create thread, errno=", errno);
117 throw TTransportException(TTransportException::NOT_OPEN,
118 " TOverlappedSubmissionThread unable to create thread");
119 }
120}
121
122TOverlappedSubmissionThread::~TOverlappedSubmissionThread() {
123 addWorkItem(&stopItem_);
124 ::WaitForSingleObject(thread_, INFINITE);
125 CloseHandle(thread_);
126}
127
128void TOverlappedSubmissionThread::run() {
129 for (;;) {
130 WaitForSingleObject(workAvailableEvent_.h, INFINITE);
131 // todo check result
132 SLIST_ENTRY* entry = NULL;
133 while ((entry = InterlockedPopEntrySList(&workList_)) != NULL) {
134 TOverlappedWorkItem& item = *static_cast<TOverlappedWorkItem*>(entry);
135 if (!item.process())
136 return;
137 }
138 }
139}
140
141unsigned __stdcall TOverlappedSubmissionThread::thread_proc(void* addr) {
142 static_cast<TOverlappedSubmissionThread*>(addr)->run();
143 return 0;
144}
145
146TCriticalSection TOverlappedSubmissionThread::instanceGuard_;
147TOverlappedSubmissionThread* TOverlappedSubmissionThread::instance_;
148uint32_t TOverlappedSubmissionThread::instanceRefCount_ = 0;
149}
150}
151} // apach::thrift::transport