pull up r24469, r24530, r24533, r24534, r24535, r24537 from trunk
[krb5.git] / src / ccapi / server / win / WorkItem.cpp
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::add(WorkItem* item) {
107     EnterCriticalSection(&cs);
108         wl.push_front(item);
109     LeaveCriticalSection(&cs);
110     return 1;
111     }
112
113 int WorkList::remove(WorkItem** item) {
114     bool    bEmpty;
115
116     bEmpty = wl.empty() & 1;
117
118     if (!bEmpty) {
119         EnterCriticalSection(&cs);
120             *item    = wl.back();
121             wl.pop_back();
122         LeaveCriticalSection(&cs);
123         }
124
125     return !bEmpty;
126     }