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 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. 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 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 63 WorkItem::WorkItem() : _buf(NULL), _rpcmsg(CCMSG_INVALID), _pipe(NULL), _sst(0) { } 64 65 WorkItem::~WorkItem() { 66 if (_buf) krb5int_ipc_stream_release(_buf); 67 if (_pipe) ccs_win_pipe_release(_pipe); 68 } 69 70 const k5_ipc_stream WorkItem::take_payload() { 71 k5_ipc_stream temp = payload(); 72 _buf = NULL; 73 return temp; 74 } 75 76 WIN_PIPE* WorkItem::take_pipe() { 77 WIN_PIPE* temp = pipe(); 78 _pipe = NULL; 79 return temp; 80 } 81 82 WorkList::WorkList() { 83 assert(InitializeCriticalSectionAndSpinCount(&cs, 0x80000400)); 84 } 85 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 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 106 int WorkList::initialize() { 107 hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 108 return 0; 109 } 110 111 int WorkList::cleanup() { 112 CloseHandle(hEvent); 113 hEvent = INVALID_HANDLE_VALUE; 114 return 0; 115 } 116 117 void WorkList::wait() { 118 WaitForSingleObject(hEvent, INFINITE); 119 } 120 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 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