ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/vendor/libpeak-0.1.2/peak/engine_client.h
Revision: 3251
Committed: Wed Apr 2 16:58:30 2014 UTC (11 years, 4 months ago) by michael
Content type: text/x-chdr
File size: 5758 byte(s)
Log Message:
- Imported libpeak-0.1.2

File Contents

# Content
1 /* PEAK Library
2 *
3 * Copyright (c) 2003
4 * Stephane Thiell <mbuna@bugged.org>. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * $Id: engine_client.h,v 1.2 2005/01/27 16:31:50 mbuna Exp $
30 */
31 #ifndef INCLUDED_PEAK_ENGINE_CLIENT_H_
32 #define INCLUDED_PEAK_ENGINE_CLIENT_H_
33
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
37
38 #include "engine.h"
39 #include "spinlock.h"
40 #include "runtime.h"
41 #include <peak/task.h>
42
43 typedef void (*peak_engine_client_event_process_func)(peak_engine_client c,
44 int event, int info);
45
46 /* Engine IO client object structure */
47 struct __peak_engine_client
48 {
49 PEAK_STRUCT_RT_HEADER;
50 peak_task _task; /* associated task */
51 peak_engine _engine; /* associated engine */
52 peak_spinlock_t _lock;
53 int _ident; /* identifier: file descriptor,
54 * signum, etc.
55 */
56 /* Optional engine dependent field.
57 */
58 #if defined(PEAK_ENGINE_POLL)
59 int _index;
60 #elif defined(PEAK_ENGINE_EPOLL)
61 uint32_t _events;
62 #endif
63
64 uint16_t _state; /* object state */
65 uint16_t _sstate; /* saved object state (sorf of
66 * cache)
67 */
68 peak_engine_client_event_process_func _ep; /* call out function ptr */
69 };
70
71 /* Bah. :)
72 */
73 #define PEAK_STRUCT_ENGINE_CLIENT_HEADER struct __peak_engine_client _c
74
75
76 #if defined(__cplusplus)
77 extern "C" {
78 #endif
79
80 /* Base class engine_client
81 */
82 PEAK_CLASS_BASE_DECLARE_VIRTUAL(engine_client);
83
84 __private_extern__ void _peak_engine_client_configure
85 (
86 peak_engine_client c,
87 int fd,
88 uint32_t state_init,
89 peak_engine_client_event_process_func ep
90 );
91
92
93 /* Lock a client to control data structure access.
94 */
95 static inline void
96 _peak_engine_client_lock(peak_engine_client c)
97 {
98 _peak_spinlock_lock(&c->_lock);
99 }
100
101 /* Unlock a client.
102 */
103 static inline void
104 _peak_engine_client_unlock(peak_engine_client c)
105 {
106 _peak_spinlock_unlock(&c->_lock);
107 }
108
109 /* Accept was performed.
110 */
111 static inline void
112 _peak_engine_client_did_accept(peak_engine_client c)
113 {
114 _peak_engine_client_lock(c);
115
116 c->_state |= CS_ACCEPTING;
117
118 /* When a client's event is currently being handled (probably by ourself,
119 * but it might be another task's thread too), we do nothing as changes
120 * will automagically be commited. Otherwise, we need to edit the client
121 * explicitely.
122 * Summary:
123 * 1. We are processing an event generated by this client... ok, we
124 * don't edit it immediately, as all changes will be commited in
125 * peak_engine_event_postprocess().
126 * 2. Events of two clients are being processed simultaneously in two
127 * task's threads. Thread of first client do an operation (accept,
128 * read or write) on second client. Probably rare, but we don't edit
129 * it immediately neither.
130 * 3. We are processing an event generated by this client, and are doing
131 * an operation on another "inactive" client (he didn't generate any
132 * event simultaneously)... oh, he needs to know! edit it now. Note that
133 * the other client could have been triggered at the same time for
134 * parallel events but have already finished his processing, then
135 * it won't commit things anymore and we need to edit it explicitely.
136 *
137 * Sure we could ignore this and edit the client every time, however
138 * some event engines like kqueue use a syscall for client's edition...
139 */
140 if (c->_engine && !(c->_state & CS_HANDLED))
141 _peak_engine_edit_client(c->_engine, c);
142
143 _peak_engine_client_unlock(c);
144 }
145
146 /* Read was performed.
147 */
148 static inline void
149 _peak_engine_client_did_read(peak_engine_client c)
150 {
151 _peak_engine_client_lock(c);
152
153 c->_state |= CS_READING;
154
155 if (c->_engine && !(c->_state & CS_HANDLED))
156 _peak_engine_edit_client(c->_engine, c);
157
158 _peak_engine_client_unlock(c);
159 }
160
161 /* Write was performed.
162 */
163 static inline void
164 _peak_engine_client_did_write(peak_engine_client c)
165 {
166 _peak_engine_client_lock(c);
167
168 c->_state |= CS_WRITING;
169
170 if (c->_engine && !(c->_state & CS_HANDLED))
171 _peak_engine_edit_client(c->_engine, c);
172
173 _peak_engine_client_unlock(c);
174 }
175
176 #if defined(__cplusplus)
177 }
178 #endif
179
180 #endif /* INCLUDED_PEAK_ENGINE_CLIENT_H_ */