- Timestamp:
- Oct 29, 2006 6:13:13 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/symbian/pjlib/src/pj/ioqueue_symbian.cpp
r788 r789 45 45 { 46 46 public: 47 CIoqueueCallback(pj_ioqueue_t *ioqueue, 48 pj_ioqueue_key_t *key, pj_sock_t sock, 49 const pj_ioqueue_callback *cb, void *user_data) 50 : CActive(CActive::EPriorityStandard), 51 ioqueue_(ioqueue), key_(key), sock_((CPjSocket*)sock), cb_(cb), 52 user_data_(user_data), aBufferPtr_(NULL, 0), type_(TYPE_NONE) 53 { 54 CActiveScheduler::Add(this); 55 } 47 static CIoqueueCallback* NewL(pj_ioqueue_t *ioqueue, 48 pj_ioqueue_key_t *key, 49 pj_sock_t sock, 50 const pj_ioqueue_callback *cb, 51 void *user_data); 56 52 57 53 // … … 60 56 pj_status_t StartRead(pj_ioqueue_op_key_t *op_key, 61 57 void *buf, pj_ssize_t *size, unsigned flags, 62 pj_sockaddr_t *addr, int *addrlen) 63 { 64 PJ_ASSERT_RETURN(IsActive()==false, PJ_EBUSY); 65 PJ_ASSERT_RETURN(pending_data_.common_.op_key_==NULL, PJ_EBUSY); 66 67 pending_data_.read_.op_key_ = op_key; 68 pending_data_.read_.addr_ = addr; 69 pending_data_.read_.addrlen_ = addrlen; 70 71 aBufferPtr_.Set((TUint8*)buf, 0, (TInt)*size); 72 73 type_ = TYPE_READ; 74 SetActive(); 75 sock_->Socket().RecvFrom(aBufferPtr_, aAddress_, flags, iStatus); 76 77 return PJ_EPENDING; 78 } 79 58 pj_sockaddr_t *addr, int *addrlen); 80 59 81 60 // … … 86 65 pj_sockaddr_t *local, 87 66 pj_sockaddr_t *remote, 88 int *addrlen ) 89 { 90 PJ_ASSERT_RETURN(IsActive()==false, PJ_EBUSY); 91 PJ_ASSERT_RETURN(pending_data_.common_.op_key_==NULL, PJ_EBUSY); 92 93 pending_data_.accept_.op_key_ = op_key; 94 pending_data_.accept_.new_sock_ = new_sock; 95 pending_data_.accept_.local_ = local; 96 pending_data_.accept_.remote_ = remote; 97 pending_data_.accept_.addrlen_ = addrlen; 98 99 // Create blank socket 100 blank_sock_.Open(PjSymbianOS::Instance()->SocketServ()); 101 102 type_ = TYPE_ACCEPT; 103 SetActive(); 104 sock_->Socket().Accept(blank_sock_, iStatus); 105 106 return PJ_EPENDING; 107 } 108 67 int *addrlen ); 109 68 110 69 // 111 70 // Completion callback. 112 71 // 113 void RunL() 114 { 115 Type cur_type = type_; 116 117 type_ = TYPE_NONE; 118 119 if (cur_type == TYPE_READ) { 120 // 121 // Completion of asynchronous RecvFrom() 122 // 123 124 /* Clear op_key (save it to temp variable first!) */ 125 pj_ioqueue_op_key_t *op_key = pending_data_.read_.op_key_; 126 pending_data_.read_.op_key_ = NULL; 127 128 // Handle failure condition 129 if (iStatus != KErrNone) { 130 cb_->on_read_complete(key_, op_key, -PJ_RETURN_OS_ERROR(iStatus.Int())); 131 return; 132 } 133 134 if (pending_data_.read_.addr_) { 135 PjSymbianOS::Addr2pj(aAddress_, 136 *(pj_sockaddr_in*)pending_data_.read_.addr_); 137 pending_data_.read_.addr_ = NULL; 138 } 139 if (pending_data_.read_.addrlen_) { 140 *pending_data_.read_.addrlen_ = sizeof(pj_sockaddr_in); 141 pending_data_.read_.addrlen_ = NULL; 142 } 143 144 /* Call callback */ 145 cb_->on_read_complete(key_, op_key, aBufferPtr_.Length()); 146 147 } else if (cur_type == TYPE_ACCEPT) { 148 // 149 // Completion of asynchronous Accept() 150 // 151 152 /* Clear op_key (save it to temp variable first!) */ 153 pj_ioqueue_op_key_t *op_key = pending_data_.read_.op_key_; 154 pending_data_.read_.op_key_ = NULL; 155 156 // Handle failure condition 157 if (iStatus != KErrNone) { 158 if (pending_data_.accept_.new_sock_) 159 *pending_data_.accept_.new_sock_ = PJ_INVALID_SOCKET; 160 161 cb_->on_accept_complete(key_, op_key, PJ_INVALID_SOCKET, 162 -PJ_RETURN_OS_ERROR(iStatus.Int())); 163 return; 164 } 165 166 CPjSocket *pjNewSock = new CPjSocket(blank_sock_); 167 168 if (pending_data_.accept_.new_sock_) { 169 *pending_data_.accept_.new_sock_ = (pj_sock_t)pjNewSock; 170 pending_data_.accept_.new_sock_ = NULL; 171 } 172 173 if (pending_data_.accept_.local_) { 174 TInetAddr aAddr; 175 blank_sock_.LocalName(aAddr); 176 PjSymbianOS::Addr2pj(aAddr, *(pj_sockaddr_in*)pending_data_.accept_.local_); 177 pending_data_.accept_.local_ = NULL; 178 } 179 180 if (pending_data_.accept_.remote_) { 181 TInetAddr aAddr; 182 blank_sock_.RemoteName(aAddr); 183 PjSymbianOS::Addr2pj(aAddr, *(pj_sockaddr_in*)pending_data_.accept_.remote_); 184 pending_data_.accept_.remote_ = NULL; 185 } 186 187 if (pending_data_.accept_.addrlen_) { 188 *pending_data_.accept_.addrlen_ = sizeof(pj_sockaddr_in); 189 pending_data_.accept_.addrlen_ = NULL; 190 } 191 192 // Call callback. 193 cb_->on_accept_complete(key_, op_key, (pj_sock_t)pjNewSock, PJ_SUCCESS); 194 } 195 196 ioqueue_->eventCount++; 197 } 72 void RunL(); 198 73 199 74 // 200 75 // CActive's DoCancel() 201 76 // 202 void DoCancel() 203 { 204 if (type_ == TYPE_READ) 205 sock_->Socket().CancelRecv(); 206 else if (type_ == TYPE_ACCEPT) 207 sock_->Socket().CancelAccept(); 208 209 type_ = TYPE_NONE; 210 } 77 void DoCancel(); 211 78 212 79 // 213 80 // Cancel operation and call callback. 214 81 // 215 void CancelOperation(pj_ioqueue_op_key_t *op_key, pj_ssize_t bytes_status) 216 { 217 Type cur_type = type_; 218 219 Cancel(); 220 221 if (cur_type == TYPE_READ) 222 cb_->on_read_complete(key_, op_key, bytes_status); 223 else if (cur_type == TYPE_ACCEPT) 224 ; 225 } 82 void CancelOperation(pj_ioqueue_op_key_t *op_key, 83 pj_ssize_t bytes_status); 226 84 227 85 // … … 293 151 union Pending_Data pending_data_; 294 152 RSocket blank_sock_; 153 154 CIoqueueCallback(pj_ioqueue_t *ioqueue, 155 pj_ioqueue_key_t *key, pj_sock_t sock, 156 const pj_ioqueue_callback *cb, void *user_data) 157 : CActive(CActive::EPriorityStandard), 158 ioqueue_(ioqueue), key_(key), sock_((CPjSocket*)sock), cb_(cb), 159 user_data_(user_data), aBufferPtr_(NULL, 0), type_(TYPE_NONE) 160 { 161 } 162 163 164 void ConstructL() 165 { 166 CActiveScheduler::Add(this); 167 } 295 168 }; 296 169 297 170 298 299 171 CIoqueueCallback* CIoqueueCallback::NewL(pj_ioqueue_t *ioqueue, 172 pj_ioqueue_key_t *key, 173 pj_sock_t sock, 174 const pj_ioqueue_callback *cb, 175 void *user_data) 176 { 177 CIoqueueCallback *self = new CIoqueueCallback(ioqueue, key, sock, 178 cb, user_data); 179 CleanupStack::PushL(self); 180 self->ConstructL(); 181 CleanupStack::Pop(self); 182 183 return self; 184 } 185 186 187 // 188 // Start asynchronous recv() operation 189 // 190 pj_status_t CIoqueueCallback::StartRead(pj_ioqueue_op_key_t *op_key, 191 void *buf, pj_ssize_t *size, 192 unsigned flags, 193 pj_sockaddr_t *addr, int *addrlen) 194 { 195 PJ_ASSERT_RETURN(IsActive()==false, PJ_EBUSY); 196 PJ_ASSERT_RETURN(pending_data_.common_.op_key_==NULL, PJ_EBUSY); 197 198 flags &= ~PJ_IOQUEUE_ALWAYS_ASYNC; 199 200 pending_data_.read_.op_key_ = op_key; 201 pending_data_.read_.addr_ = addr; 202 pending_data_.read_.addrlen_ = addrlen; 203 204 aBufferPtr_.Set((TUint8*)buf, 0, (TInt)*size); 205 206 type_ = TYPE_READ; 207 if (addr && addrlen) { 208 sock_->Socket().RecvFrom(aBufferPtr_, aAddress_, flags, iStatus); 209 } else { 210 aAddress_.SetAddress(0); 211 aAddress_.SetPort(0); 212 sock_->Socket().Recv(aBufferPtr_, flags, iStatus); 213 } 214 215 if (iStatus==KRequestPending) { 216 SetActive(); 217 return PJ_EPENDING; 218 } else { 219 return PJ_RETURN_OS_ERROR(iStatus.Int()); 220 } 221 } 222 223 224 // 225 // Start asynchronous accept() operation. 226 // 227 pj_status_t CIoqueueCallback::StartAccept(pj_ioqueue_op_key_t *op_key, 228 pj_sock_t *new_sock, 229 pj_sockaddr_t *local, 230 pj_sockaddr_t *remote, 231 int *addrlen ) 232 { 233 PJ_ASSERT_RETURN(IsActive()==false, PJ_EBUSY); 234 PJ_ASSERT_RETURN(pending_data_.common_.op_key_==NULL, PJ_EBUSY); 235 236 pending_data_.accept_.op_key_ = op_key; 237 pending_data_.accept_.new_sock_ = new_sock; 238 pending_data_.accept_.local_ = local; 239 pending_data_.accept_.remote_ = remote; 240 pending_data_.accept_.addrlen_ = addrlen; 241 242 // Create blank socket 243 blank_sock_.Open(PjSymbianOS::Instance()->SocketServ()); 244 245 type_ = TYPE_ACCEPT; 246 sock_->Socket().Accept(blank_sock_, iStatus); 247 248 if (iStatus==KRequestPending) { 249 SetActive(); 250 return PJ_EPENDING; 251 } else { 252 return PJ_RETURN_OS_ERROR(iStatus.Int()); 253 } 254 } 255 256 257 // 258 // Completion callback. 259 // 260 void CIoqueueCallback::RunL() 261 { 262 Type cur_type = type_; 263 264 type_ = TYPE_NONE; 265 266 if (cur_type == TYPE_READ) { 267 // 268 // Completion of asynchronous RecvFrom() 269 // 270 271 /* Clear op_key (save it to temp variable first!) */ 272 pj_ioqueue_op_key_t *op_key = pending_data_.read_.op_key_; 273 pending_data_.read_.op_key_ = NULL; 274 275 // Handle failure condition 276 if (iStatus != KErrNone) { 277 cb_->on_read_complete(key_, op_key, 278 -PJ_RETURN_OS_ERROR(iStatus.Int())); 279 return; 280 } 281 282 if (pending_data_.read_.addr_) { 283 PjSymbianOS::Addr2pj(aAddress_, 284 *(pj_sockaddr_in*)pending_data_.read_.addr_); 285 pending_data_.read_.addr_ = NULL; 286 } 287 if (pending_data_.read_.addrlen_) { 288 *pending_data_.read_.addrlen_ = sizeof(pj_sockaddr_in); 289 pending_data_.read_.addrlen_ = NULL; 290 } 291 292 /* Call callback */ 293 cb_->on_read_complete(key_, op_key, aBufferPtr_.Length()); 294 295 } else if (cur_type == TYPE_ACCEPT) { 296 // 297 // Completion of asynchronous Accept() 298 // 299 300 /* Clear op_key (save it to temp variable first!) */ 301 pj_ioqueue_op_key_t *op_key = pending_data_.read_.op_key_; 302 pending_data_.read_.op_key_ = NULL; 303 304 // Handle failure condition 305 if (iStatus != KErrNone) { 306 if (pending_data_.accept_.new_sock_) 307 *pending_data_.accept_.new_sock_ = PJ_INVALID_SOCKET; 308 309 cb_->on_accept_complete(key_, op_key, PJ_INVALID_SOCKET, 310 -PJ_RETURN_OS_ERROR(iStatus.Int())); 311 return; 312 } 313 314 CPjSocket *pjNewSock = new CPjSocket(blank_sock_); 315 316 if (pending_data_.accept_.new_sock_) { 317 *pending_data_.accept_.new_sock_ = (pj_sock_t)pjNewSock; 318 pending_data_.accept_.new_sock_ = NULL; 319 } 320 321 if (pending_data_.accept_.local_) { 322 TInetAddr aAddr; 323 pj_sockaddr_in *ptr_sockaddr; 324 325 blank_sock_.LocalName(aAddr); 326 ptr_sockaddr = (pj_sockaddr_in*)pending_data_.accept_.local_; 327 PjSymbianOS::Addr2pj(aAddr, *ptr_sockaddr); 328 pending_data_.accept_.local_ = NULL; 329 } 330 331 if (pending_data_.accept_.remote_) { 332 TInetAddr aAddr; 333 pj_sockaddr_in *ptr_sockaddr; 334 335 blank_sock_.RemoteName(aAddr); 336 ptr_sockaddr = (pj_sockaddr_in*)pending_data_.accept_.remote_; 337 PjSymbianOS::Addr2pj(aAddr, *ptr_sockaddr); 338 pending_data_.accept_.remote_ = NULL; 339 } 340 341 if (pending_data_.accept_.addrlen_) { 342 *pending_data_.accept_.addrlen_ = sizeof(pj_sockaddr_in); 343 pending_data_.accept_.addrlen_ = NULL; 344 } 345 346 // Call callback. 347 cb_->on_accept_complete(key_, op_key, (pj_sock_t)pjNewSock, 348 PJ_SUCCESS); 349 } 350 351 ioqueue_->eventCount++; 352 } 353 354 // 355 // CActive's DoCancel() 356 // 357 void CIoqueueCallback::DoCancel() 358 { 359 if (type_ == TYPE_READ) 360 sock_->Socket().CancelRecv(); 361 else if (type_ == TYPE_ACCEPT) 362 sock_->Socket().CancelAccept(); 363 364 type_ = TYPE_NONE; 365 } 366 367 // 368 // Cancel operation and call callback. 369 // 370 void CIoqueueCallback::CancelOperation(pj_ioqueue_op_key_t *op_key, 371 pj_ssize_t bytes_status) 372 { 373 Type cur_type = type_; 374 375 Cancel(); 376 377 if (cur_type == TYPE_READ) 378 cb_->on_read_complete(key_, op_key, bytes_status); 379 else if (cur_type == TYPE_ACCEPT) 380 ; 381 } 382 383 384 ///////////////////////////////////////////////////////////////////////////// 300 385 /* 301 386 * IO Queue key structure. … … 376 461 pj_ioqueue_key_t *key; 377 462 378 key = (pj_ioqueue_key_t*) pj_pool_ alloc(pool, sizeof(pj_ioqueue_key_t));379 key->cbObj = new CIoqueueCallback(ioq, key, sock, cb, user_data);463 key = (pj_ioqueue_key_t*) pj_pool_zalloc(pool, sizeof(pj_ioqueue_key_t)); 464 key->cbObj = CIoqueueCallback::NewL(ioq, key, sock, cb, user_data); 380 465 381 466 *p_key = key; … … 390 475 if (key == NULL || key->cbObj == NULL) 391 476 return PJ_SUCCESS; 477 478 // Cancel pending async object 479 if (key->cbObj && key->cbObj->IsActive()) { 480 key->cbObj->Cancel(); 481 } 392 482 393 483 // Close socket. … … 395 485 delete key->cbObj->get_pj_socket(); 396 486 397 // Delete async object 398 delete key->cbObj; 399 key->cbObj = NULL; 487 // Delete async object. 488 if (key->cbObj) { 489 delete key->cbObj; 490 key->cbObj = NULL; 491 } 400 492 401 493 return PJ_SUCCESS; … … 519 611 520 612 if (timeout) { 521 if (!ioq->timeoutTimer->IsActive()) 613 //if (!ioq->timeoutTimer->IsActive()) 614 if (0) 522 615 timer = ioq->timeoutTimer; 523 616 else … … 534 627 do { 535 628 PjSymbianOS::Instance()->WaitForActiveObjects(); 536 } while (ioq->eventCount == 0 && !timer->HasTimedOut());537 538 if ( !timer->HasTimedOut())629 } while (ioq->eventCount == 0 && (!timer || (timer && !timer->HasTimedOut()))); 630 631 if (timer && !timer->HasTimedOut()) 539 632 timer->Cancel(); 540 633 541 if (timer != ioq->timeoutTimer)634 if (timer && timer != ioq->timeoutTimer) 542 635 delete timer; 543 636 … … 555 648 pj_uint32_t flags ) 556 649 { 557 return pj_ioqueue_recvfrom(key, op_key, buffer, length, flags, NULL, NULL); 650 // Clear flag 651 flags &= ~PJ_IOQUEUE_ALWAYS_ASYNC; 652 return key->cbObj->StartRead(op_key, buffer, length, flags, NULL, NULL); 558 653 } 559 654 … … 575 670 return PJ_EBUSY; 576 671 672 // Clear flag 673 flags &= ~PJ_IOQUEUE_ALWAYS_ASYNC; 577 674 return key->cbObj->StartRead(op_key, buffer, length, flags, addr, addrlen); 578 675 } … … 597 694 PJ_ASSERT_RETURN((flags & PJ_IOQUEUE_ALWAYS_ASYNC)==0, PJ_EINVAL); 598 695 696 // Clear flag 697 flags &= ~PJ_IOQUEUE_ALWAYS_ASYNC; 698 599 699 key->cbObj->get_pj_socket()->Socket().Send(aBuffer, flags, reqStatus, aLen); 600 700 User::WaitForRequest(reqStatus); … … 603 703 return PJ_RETURN_OS_ERROR(reqStatus.Int()); 604 704 605 *length = aLen.Length(); 705 //At least in UIQ Emulator, aLen.Length() reports incorrect length 706 //for UDP (some newlc.com users seem to have reported this too). 707 //*length = aLen.Length(); 606 708 return PJ_SUCCESS; 607 709 } … … 632 734 PJ_ASSERT_RETURN(addrlen == sizeof(pj_sockaddr_in), PJ_EINVAL); 633 735 736 // Clear flag 737 flags &= ~PJ_IOQUEUE_ALWAYS_ASYNC; 738 634 739 aBuffer.Set((const TUint8*)data, (TInt)*length); 635 740 PjSymbianOS::pj2Addr(*(const pj_sockaddr_in*)addr, inetAddr); 636 741 CPjSocket *pjSock = key->cbObj->get_pj_socket(); 637 742 638 pjSock->Socket().Send (aBuffer, flags, reqStatus, aLen);743 pjSock->Socket().SendTo(aBuffer, inetAddr, flags, reqStatus, aLen); 639 744 User::WaitForRequest(reqStatus); 640 745 … … 642 747 return PJ_RETURN_OS_ERROR(reqStatus.Int()); 643 748 644 *length = aLen.Length(); 645 return PJ_SUCCESS; 646 } 647 749 //At least in UIQ Emulator, aLen.Length() reports incorrect length 750 //for UDP (some newlc.com users seem to have reported this too). 751 //*length = aLen.Length(); 752 return PJ_SUCCESS; 753 } 754
Note: See TracChangeset
for help on using the changeset viewer.