正在显示
1 个修改的文件
包含
175 行增加
和
0 行删除
src/server/spserver/spiochannel.cpp
0 → 100644
1 | +/* | |
2 | + * Copyright 2007 Stephen Liu | |
3 | + * For license terms, see the file COPYING along with this library. | |
4 | + */ | |
5 | + | |
6 | +#include <string.h> | |
7 | +#include <assert.h> | |
8 | + | |
9 | +#include "spporting.hpp" | |
10 | + | |
11 | +#include "spiochannel.hpp" | |
12 | + | |
13 | +#include "sputils.hpp" | |
14 | +#include "spresponse.hpp" | |
15 | +#include "spsession.hpp" | |
16 | +#include "spbuffer.hpp" | |
17 | +#include "spmsgblock.hpp" | |
18 | + | |
19 | +#ifdef WIN32 | |
20 | +#include "spwin32buffer.hpp" | |
21 | +#include "spiocpevent.hpp" | |
22 | +#include "spwin32iocp.hpp" | |
23 | +#else | |
24 | +#include "speventcb.hpp" | |
25 | +#include "event.h" | |
26 | +#endif | |
27 | + | |
28 | +//--------------------------------------------------------- | |
29 | + | |
30 | +SP_IOChannel :: ~SP_IOChannel() | |
31 | +{ | |
32 | +} | |
33 | + | |
34 | +sp_evbuffer_t * SP_IOChannel :: getEvBuffer( SP_Buffer * buffer ) | |
35 | +{ | |
36 | + return buffer->mBuffer; | |
37 | +} | |
38 | + | |
39 | +int SP_IOChannel :: transmit( SP_Session * session ) | |
40 | +{ | |
41 | +#ifdef WIN32 | |
42 | + const static int SP_MAX_IOV = MSG_MAXIOVLEN; | |
43 | + | |
44 | + SP_IocpSession_t * iocpSession = (SP_IocpSession_t*)session->getArg(); | |
45 | + SP_IocpEventArg * eventArg = iocpSession->mEventArg; | |
46 | +#else | |
47 | +# ifdef IOV_MAX | |
48 | + const static int SP_MAX_IOV = IOV_MAX; | |
49 | +# else | |
50 | + const static int SP_MAX_IOV = 8; | |
51 | +# endif | |
52 | + SP_EventArg * eventArg = (SP_EventArg*)session->getArg(); | |
53 | +#endif | |
54 | + | |
55 | + SP_ArrayList * outList = session->getOutList(); | |
56 | + size_t outOffset = session->getOutOffset(); | |
57 | + | |
58 | + struct iovec iovArray[ SP_MAX_IOV ]; | |
59 | + memset( iovArray, 0, sizeof( iovArray ) ); | |
60 | + | |
61 | + int iovSize = 0; | |
62 | + | |
63 | + for( int i = 0; i < outList->getCount() && iovSize < SP_MAX_IOV; i++ ) { | |
64 | + SP_Message * msg = (SP_Message*)outList->getItem( i ); | |
65 | + | |
66 | + if( outOffset >= msg->getMsg()->getSize() ) { | |
67 | + outOffset -= msg->getMsg()->getSize(); | |
68 | + } else { | |
69 | + iovArray[ iovSize ].iov_base = (char*)msg->getMsg()->getBuffer() + outOffset; | |
70 | + iovArray[ iovSize++ ].iov_len = msg->getMsg()->getSize() - outOffset; | |
71 | + outOffset = 0; | |
72 | + } | |
73 | + | |
74 | + SP_MsgBlockList * blockList = msg->getFollowBlockList(); | |
75 | + for( int j = 0; j < blockList->getCount() && iovSize < SP_MAX_IOV; j++ ) { | |
76 | + SP_MsgBlock * block = (SP_MsgBlock*)blockList->getItem( j ); | |
77 | + | |
78 | + if( outOffset >= block->getSize() ) { | |
79 | + outOffset -= block->getSize(); | |
80 | + } else { | |
81 | + iovArray[ iovSize ].iov_base = (char*)block->getData() + outOffset; | |
82 | + iovArray[ iovSize++ ].iov_len = block->getSize() - outOffset; | |
83 | + outOffset = 0; | |
84 | + } | |
85 | + } | |
86 | + } | |
87 | + | |
88 | + int len = write_vec( iovArray, iovSize ); | |
89 | + | |
90 | + if( len > 0 ) { | |
91 | + outOffset = session->getOutOffset() + len; | |
92 | + | |
93 | + for( ; outList->getCount() > 0; ) { | |
94 | + SP_Message * msg = (SP_Message*)outList->getItem( 0 ); | |
95 | + if( outOffset >= msg->getTotalSize() ) { | |
96 | + msg = (SP_Message*)outList->takeItem( 0 ); | |
97 | + outOffset = outOffset - msg->getTotalSize(); | |
98 | + | |
99 | + int index = msg->getToList()->find( session->getSid() ); | |
100 | + if( index >= 0 ) msg->getToList()->take( index ); | |
101 | + msg->getSuccess()->add( session->getSid() ); | |
102 | + | |
103 | + if( msg->getToList()->getCount() <= 0 ) { | |
104 | + eventArg->getOutputResultQueue()->push( msg ); | |
105 | + } | |
106 | + } else { | |
107 | + break; | |
108 | + } | |
109 | + } | |
110 | + | |
111 | + session->setOutOffset( outOffset ); | |
112 | + } | |
113 | + | |
114 | + if( len > 0 && outList->getCount() > 0 ) { | |
115 | + int tmpLen = transmit( session ); | |
116 | + if( tmpLen > 0 ) len += tmpLen; | |
117 | + } | |
118 | + | |
119 | + return len; | |
120 | +} | |
121 | + | |
122 | +//--------------------------------------------------------- | |
123 | + | |
124 | +SP_IOChannelFactory :: ~SP_IOChannelFactory() | |
125 | +{ | |
126 | +} | |
127 | + | |
128 | +//--------------------------------------------------------- | |
129 | + | |
130 | +SP_DefaultIOChannel :: SP_DefaultIOChannel() | |
131 | +{ | |
132 | + mFd = -1; | |
133 | +} | |
134 | + | |
135 | +SP_DefaultIOChannel :: ~SP_DefaultIOChannel() | |
136 | +{ | |
137 | + mFd = -1; | |
138 | +} | |
139 | + | |
140 | +int SP_DefaultIOChannel :: init( int fd ) | |
141 | +{ | |
142 | + mFd = fd; | |
143 | + | |
144 | + return 0; | |
145 | +} | |
146 | + | |
147 | +int SP_DefaultIOChannel :: receive( SP_Session * session ) | |
148 | +{ | |
149 | +#ifdef WIN32 | |
150 | + return spwin32buffer_read( getEvBuffer( session->getInBuffer() ), mFd, -1 ); | |
151 | +#else | |
152 | + return evbuffer_read( getEvBuffer( session->getInBuffer() ), mFd, -1 ); | |
153 | +#endif | |
154 | +} | |
155 | + | |
156 | +int SP_DefaultIOChannel :: write_vec( struct iovec * iovArray, int iovSize ) | |
157 | +{ | |
158 | + return sp_writev( mFd, iovArray, iovSize ); | |
159 | +} | |
160 | + | |
161 | +//--------------------------------------------------------- | |
162 | + | |
163 | +SP_DefaultIOChannelFactory :: SP_DefaultIOChannelFactory() | |
164 | +{ | |
165 | +} | |
166 | + | |
167 | +SP_DefaultIOChannelFactory :: ~SP_DefaultIOChannelFactory() | |
168 | +{ | |
169 | +} | |
170 | + | |
171 | +SP_IOChannel * SP_DefaultIOChannelFactory :: create() const | |
172 | +{ | |
173 | + return new SP_DefaultIOChannel(); | |
174 | +} | |
175 | + | ... | ... |
请
注册
或
登录
后发表评论