1 /*
2 * $Header$
3 *
4 * Copyright 2008 Massachusetts Institute of Technology.
5 * All Rights Reserved.
6 *
7 * Export of this software from the United States of America may
8 * require a specific license from the United States Government.
9 * It is the responsibility of any person or organization contemplating
10 * export to obtain such a license before exporting.
11 *
12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13 * distribute this software and its documentation for any purpose and
14 * without fee is hereby granted, provided that the above copyright
15 * notice appear in all copies and that both that copyright notice and
16 * this permission notice appear in supporting documentation, and that
17 * the name of M.I.T. not be used in advertising or publicity pertaining
18 * to distribution of the software without specific, written prior
19 * permission. Furthermore if you modify this software you must label
20 * your software as modified software and not distribute it in such a
21 * fashion that it might be confused with the original M.I.T. software.
22 * M.I.T. makes no representations about the suitability of
23 * this software for any purpose. It is provided "as is" without express
24 * or implied warranty.
25 */
26
27 #include <string.h>
28 #include "assert.h"
29
30 #pragma warning (disable : 4996)
31
32 #include "win-utils.h"
33 #include "WorkItem.h"
34
35 extern "C" {
36 #include "cci_debugging.h"
37 }
38
39 // CountedBuffer makes a copy of the data. Each CountedBuffer must be deleted.
40
deleteBuffer(char ** buf)41 void deleteBuffer(char** buf) {
42 if (*buf) {
43 delete [](*buf);
44 *buf = NULL;
45 }
46 }
47
48 // WorkItem contains a CountedBuffer which must be deleted,
49 // so each WorkItem must be deleted.
WorkItem(k5_ipc_stream buf,WIN_PIPE * pipe,const long type,const long sst)50 WorkItem::WorkItem(k5_ipc_stream buf, WIN_PIPE* pipe, const long type, const long sst)
51 : _buf(buf), _rpcmsg(type), _pipe(pipe), _sst(sst) { }
52
WorkItem(const WorkItem & item)53 WorkItem::WorkItem(const WorkItem& item) : _buf(NULL), _rpcmsg(0), _pipe(NULL), _sst(0) {
54
55 k5_ipc_stream _buf = NULL;
56 krb5int_ipc_stream_new(&_buf);
57 krb5int_ipc_stream_write(_buf,
58 krb5int_ipc_stream_data(item.payload()),
59 krb5int_ipc_stream_size(item.payload()) );
60 WorkItem(_buf, item._pipe, item._rpcmsg, item._sst);
61 }
62
WorkItem()63 WorkItem::WorkItem() : _buf(NULL), _rpcmsg(CCMSG_INVALID), _pipe(NULL), _sst(0) { }
64
~WorkItem()65 WorkItem::~WorkItem() {
66 if (_buf) krb5int_ipc_stream_release(_buf);
67 if (_pipe) ccs_win_pipe_release(_pipe);
68 }
69
take_payload()70 const k5_ipc_stream WorkItem::take_payload() {
71 k5_ipc_stream temp = payload();
72 _buf = NULL;
73 return temp;
74 }
75
take_pipe()76 WIN_PIPE* WorkItem::take_pipe() {
77 WIN_PIPE* temp = pipe();
78 _pipe = NULL;
79 return temp;
80 }
81
WorkList()82 WorkList::WorkList() {
83 assert(InitializeCriticalSectionAndSpinCount(&cs, 0x80000400));
84 }
85
~WorkList()86 WorkList::~WorkList() {
87 // Delete any WorkItems in the queue:
88 WorkItem* item;
89 cci_debug_printf("%s", __FUNCTION__);
90 char buf[2048];
91 char* pbuf = (char*)buf;
92 while (remove(&item)) {
93 cci_debug_printf("WorkList::~WorkList() deleting %s", item->print(pbuf));
94 delete item;
95 }
96
97 DeleteCriticalSection(&cs);
98 }
99
print(char * buf)100 char* WorkItem::print(char* buf) {
101 sprintf(buf, "WorkItem msg#:%d sst:%ld pipe:<%s>/0x%X", _rpcmsg, _sst,
102 ccs_win_pipe_getUuid(_pipe), ccs_win_pipe_getHandle(_pipe));
103 return buf;
104 }
105
initialize()106 int WorkList::initialize() {
107 hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
108 return 0;
109 }
110
cleanup()111 int WorkList::cleanup() {
112 CloseHandle(hEvent);
113 hEvent = INVALID_HANDLE_VALUE;
114 return 0;
115 }
116
wait()117 void WorkList::wait() {
118 WaitForSingleObject(hEvent, INFINITE);
119 }
120
add(WorkItem * item)121 int WorkList::add(WorkItem* item) {
122 EnterCriticalSection(&cs);
123 wl.push_front(item);
124 LeaveCriticalSection(&cs);
125 SetEvent(hEvent);
126 return 1;
127 }
128
remove(WorkItem ** item)129 int WorkList::remove(WorkItem** item) {
130 bool bEmpty;
131
132 bEmpty = wl.empty() & 1;
133
134 if (!bEmpty) {
135 EnterCriticalSection(&cs);
136 *item = wl.back();
137 wl.pop_back();
138 LeaveCriticalSection(&cs);
139 }
140
141 return !bEmpty;
142 }
143