xref: /freebsd/crypto/krb5/src/ccapi/server/win/WorkItem.cpp (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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