/home/dko/projects/mobilec/trunk/src/acc.c

Go to the documentation of this file.
00001 /* SVN FILE INFO
00002  * $Revision: 174 $ : Last Committed Revision
00003  * $Date: 2008年06月24日 10:50:29 -0700 (2008年6月24日) $ : Last Committed Date */
00004 /*[
00005  * Copyright (c) 2007 Integration Engineering Laboratory
00006  University of California, Davis
00007  *
00008  * Permission to use, copy, and distribute this software and its
00009  * documentation for any purpose with or without fee is hereby granted,
00010  * provided that the above copyright notice appear in all copies and
00011  * that both that copyright notice and this permission notice appear
00012  * in supporting documentation.
00013  *
00014  * Permission to modify the software is granted, but not the right to
00015  * distribute the complete modified source code. Modifications are to
00016  * be distributed as patches to the released version. Permission to
00017  * distribute binaries produced by compiling modified sources is granted,
00018  * provided you
00019  * 1. distribute the corresponding source modifications from the
00020  * released version in the form of a patch file along with the binaries,
00021  * 2. add special version identification to distinguish your version
00022  * in addition to the base release version number,
00023  * 3. provide your name and address as the primary contact for the
00024  * support of your modified version, and
00025  * 4. retain our contact information in regard to use of the base
00026  * software.
00027  * Permission to distribute the released version of the source code along
00028  * with corresponding source modifications in the form of a patch file is
00029  * granted with same provisions 2 through 4 for binary distributions.
00030  *
00031  * This software is provided "as is" without express or implied warranty
00032  * to the extent permitted by applicable law.
00033 ]*/
00034 
00035 #ifndef _WIN32
00036 #include <sys/socket.h>
00037 #include <arpa/inet.h>
00038 #include <netinet/in.h>
00039 #include <netdb.h>
00040 #include <sys/un.h>
00041 #include <unistd.h>
00042 #include <sys/time.h>
00043 #include <netdb.h>
00044 #include <pthread.h>
00045 #else
00046 #include <winsock.h>
00047 #include <windows.h>
00048 #include <time.h>
00049 #endif
00050 
00051 #include <stdlib.h>
00052 #include "include/acc.h"
00053 #include "include/connection.h"
00054 #include "include/data_structures.h"
00055 #include "include/macros.h"
00056 #include "include/mc_error.h"
00057 #include "include/mc_platform.h"
00058 #include "include/message.h"
00059 #include "include/mtp_http.h"
00060 #include "include/xml_parser.h"
00061 #include "include/fipa_acl_envelope.h"
00062 
00063 #define BACKLOG 10
00064 
00065 acc_p
00066 acc_Initialize(struct mc_platform_s* mc_platform)
00067 {
00068 acc_p acc;
00069 acc = (acc_p)malloc(sizeof(acc_t));
00070 acc->mc_platform = mc_platform;
00071 
00072 acc->waiting = 0;
00073 acc->waiting_lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00074 MUTEX_INIT(acc->waiting_lock);
00075 acc->waiting_cond = (COND_T*)malloc(sizeof(COND_T));
00076 COND_INIT(acc->waiting_cond);
00077 
00078 return acc;
00079 }
00080 
00081 int 
00082 acc_Destroy(acc_p acc)
00083 {
00084 if(acc == NULL) {
00085 return MC_SUCCESS;
00086 }
00087 free(acc);
00088 acc = NULL;
00089 return MC_SUCCESS;
00090 }
00091 
00092 #ifndef _WIN32
00093 void*
00094 acc_MessageHandlerThread(void* arg)
00095 #else
00096 DWORD WINAPI
00097 acc_MessageHandlerThread(LPVOID arg)
00098 #endif
00099 {
00100 mc_platform_p mc_platform = (mc_platform_p)arg;
00101 message_p message;
00102 agent_p agent;
00103 int mobile_agent_counter = 1;
00104 char* tmpstr;
00105 char* origname;
00106 int i;
00107 
00108 while(1) 
00109 {
00110 MUTEX_LOCK(mc_platform->message_queue->lock);
00111 MUTEX_LOCK(mc_platform->quit_lock);
00112 while(mc_platform->message_queue->size == 0 && !mc_platform->quit) {
00113 MUTEX_UNLOCK(mc_platform->quit_lock);
00114 COND_WAIT(
00115 mc_platform->message_queue->cond,
00116 mc_platform->message_queue->lock );
00117 MUTEX_LOCK(mc_platform->quit_lock);
00118 }
00119 if (mc_platform->message_queue->size == 0 && mc_platform->quit)
00120 {
00121 MUTEX_UNLOCK(mc_platform->quit_lock);
00122 MUTEX_UNLOCK(mc_platform->message_queue->lock);
00123 return 0;
00124 }
00125 
00126 MUTEX_UNLOCK(mc_platform->quit_lock);
00127 MUTEX_UNLOCK(mc_platform->message_queue->lock);
00128 message = message_queue_Pop(mc_platform->message_queue);
00129 if (message == NULL) {
00130 printf("POP ERROR\n");
00131 continue;
00132 }
00133 /* Send MC Signal */
00134 MUTEX_LOCK(mc_platform->MC_signal_lock);
00135 mc_platform->MC_signal = MC_RECV_MESSAGE;
00136 COND_BROADCAST(mc_platform->MC_signal_cond);
00137 MUTEX_UNLOCK(mc_platform->MC_signal_lock);
00138 MUTEX_LOCK(mc_platform->giant_lock);
00139 while(mc_platform->giant == 0) {
00140 COND_WAIT (
00141 mc_platform->giant_cond,
00142 mc_platform->giant_lock);
00143 }
00144 MUTEX_UNLOCK(mc_platform->giant_lock);
00145 /* See if the destination is here. If it is, process the message.
00146  * Otherwise, send the message to it's destination */
00147 if(message->to_address == NULL) {
00148 /* Process message. Create the agent if it is an agent, or
00149  * process the ACL if it's an ACL message. */
00150 switch(message->message_type) {
00151 case MOBILE_AGENT:
00152 agent = agent_Initialize(
00153 mc_platform,
00154 message,
00155 mobile_agent_counter);
00156 if (agent != NULL) {
00157 /* We need to make sure there are no agent-name collisions. */
00158 i = 1;
00159 if(agent_queue_SearchName(mc_platform->agent_queue, agent->name)) {
00160 origname = agent->name;
00161 while(agent_queue_SearchName(mc_platform->agent_queue, agent->name)) {
00162 /* An agent with a matching name was found! For now, let us just
00163  * rename the agent. */
00164 tmpstr = (char*)malloc(sizeof(char) * strlen(origname) + 7);
00165 sprintf(tmpstr, "%s_%04d", origname, i);
00166 agent->name = tmpstr;
00167 i++;
00168 }
00169 fprintf(stderr, "Warning: Agent '%s' has been renamed to '%s'.\n",
00170 origname, agent->name);
00171 free(origname);
00172 }
00173 mobile_agent_counter++;
00174 agent_queue_Add(
00175 mc_platform->agent_queue,
00176 agent);
00177 }
00178 message_Destroy(message);
00179 /* Send MC_Signal */
00180 MUTEX_LOCK(mc_platform->MC_signal_lock);
00181 mc_platform->MC_signal = MC_RECV_AGENT;
00182 COND_BROADCAST(mc_platform->MC_signal_cond);
00183 MUTEX_UNLOCK(mc_platform->MC_signal_lock);
00184 MUTEX_LOCK(mc_platform->giant_lock);
00185 while(mc_platform->giant == 0) {
00186 COND_WAIT(mc_platform->giant_cond,
00187 mc_platform->giant_lock);
00188 }
00189 MUTEX_UNLOCK(mc_platform->giant_lock);
00190 /* Set the ams to run */
00191 MUTEX_LOCK(mc_platform->ams->runflag_lock);
00192 mc_platform->ams->run = 1;
00193 COND_BROADCAST(mc_platform->ams->runflag_cond);
00194 MUTEX_UNLOCK(mc_platform->ams->runflag_lock);
00195 break;
00196 case FIPA_ACL:
00197 /* This case should never happen now, due to a reorganization
00198  * of MobileC. This enum will be deprecated in a future release. */
00199 break;
00200 case RETURN_MSG:
00201 /* Add the persistent neutral agent. */
00202 agent = agent_Initialize(
00203 mc_platform,
00204 message,
00205 mobile_agent_counter);
00206 if (agent != NULL) {
00207 MUTEX_LOCK(agent->lock);
00208 agent->datastate->persistent = 1;
00209 agent->agent_status = MC_AGENT_NEUTRAL;
00210 MUTEX_UNLOCK(agent->lock);
00211 mobile_agent_counter++;
00212 agent_queue_Add(
00213 mc_platform->agent_queue,
00214 agent);
00215 }
00216 message_Destroy(message);
00217 /* Send MC_Signal */
00218 MUTEX_LOCK(mc_platform->MC_signal_lock);
00219 mc_platform->MC_signal = MC_RECV_RETURN;
00220 COND_BROADCAST(mc_platform->MC_signal_cond);
00221 MUTEX_UNLOCK(mc_platform->MC_signal_lock);
00222 MUTEX_LOCK(mc_platform->giant_lock);
00223 while(mc_platform->giant == 0) {
00224 COND_WAIT(
00225 mc_platform->giant_cond,
00226 mc_platform->giant_lock);
00227 }
00228 MUTEX_UNLOCK(mc_platform->giant_lock);
00229 /* Set the ams to run */
00230 MUTEX_LOCK(mc_platform->ams->runflag_lock);
00231 mc_platform->ams->run = 1;
00232 COND_BROADCAST(mc_platform->ams->runflag_cond);
00233 MUTEX_UNLOCK(mc_platform->ams->runflag_lock);
00234 break;
00235 /* MC_SECURITY */
00236 #ifdef MC_SECURITY
00237 case ENCRYPTED_DATA:
00238 if (mc_platform->enable_security) {
00239 message_queue_Add
00240 (
00241 mc_platform->asm_message_queue,
00242 message
00243 );
00244 } else {
00245 WARN("mc_security not enabled. Discarding ENCRYPTED_DATA message.");
00246 message_Destroy(message);
00247 }
00248 break;
00249 case ENCRYPTION_INITIALIZE: 
00250 if (mc_platform->enable_security) {
00251 asm_queue_Add
00252 (
00253 mc_platform->asm_queue,
00254 asm_node_Initialize(message, mc_platform->security_manager)
00255 );
00256 /* Manually wake up the asm thread */
00257 MUTEX_LOCK(mc_platform->asm_message_queue->lock);
00258 COND_SIGNAL(mc_platform->asm_message_queue->cond);
00259 MUTEX_UNLOCK(mc_platform->asm_message_queue->lock);
00260 message_Destroy(message);
00261 } else {
00262 WARN("mc_security not enabled. Discarding ENCRYPTION_INITIALIZE message.");
00263 message_Destroy(message);
00264 }
00265 break;
00266 case REQUEST_ENCRYPTION_INITIALIZE:
00267 if (mc_platform->enable_security) {
00268 asm_SendEncryptionData(
00269 mc_platform->security_manager,
00270 message->from_address
00271 );
00272 message_Destroy(message);
00273 } else {
00274 WARN("mc_security not enabled. Discarding REQUEST_ENCRYPTION_INITIALIZE message.");
00275 message_Destroy(message);
00276 }
00277 break;
00278 #endif /* END MC_SECURITY */
00279 case RELAY:
00280 case REQUEST:
00281 case SUBSCRIBE:
00282 case CANCEL:
00283 case N_UNDRSTD:
00284 case QUER_IF:
00285 case QUER_REF:
00286 case AGENT_UPDATE:
00287 fprintf(stderr, "FIXME: Message type %d not processable.%s:%d\n",
00288 message->message_type, __FILE__, __LINE__ );
00289 message_Destroy(message);
00290 break;
00291 default:
00292 fprintf(stderr, "Unknown message type:%d %s:%d\n",
00293 message->message_type, __FILE__, __LINE__);
00294 message_Destroy(message);
00295 }
00296 } else {
00297 #ifdef MC_SECURITY
00298 if (mc_platform->enable_security) {
00299 if (
00300 (message->message_type != ENCRYPTED_DATA) &&
00301 (message->message_type != ENCRYPTION_INITIALIZE) &&
00302 (message->message_type != REQUEST_ENCRYPTION_INITIALIZE)
00303 )
00304 {
00305 message_queue_Add
00306 (
00307 mc_platform->asm_message_queue,
00308 message
00309 );
00310 continue;
00311 }
00312 }
00313 #endif
00314 message_Send
00315 (
00316 message
00317 );
00318 message_Destroy
00319 (
00320 message
00321 );
00322 }
00323 }
00324 return 0;
00325 }
00326 
00327 #ifndef _WIN32
00328 void*
00329 acc_Thread(void* arg)
00330 #else
00331 DWORD WINAPI
00332 acc_Thread( LPVOID arg )
00333 #endif
00334 {
00335 connection_p connection;
00336 message_p message;
00337 mtp_http_p mtp_http;
00338 mc_platform_p mc_platform = (mc_platform_p)arg;
00339 fipa_acl_envelope_p fipa_envelope;
00340 fipa_acl_message_p fipa_message;
00341 fipa_message_string_p fipa_message_string;
00342 int err;
00343 int i, j;
00344 agent_t* agent;
00345 /* We want to watch the connectlist for incoming connections, initialize 
00346  * them into messages, and add the messages to the appropriate queue. */
00347 while(1) {
00348 connection = NULL;
00349 message = NULL;
00350 mtp_http = NULL;
00351 MUTEX_LOCK(mc_platform->connection_queue->lock);
00352 MUTEX_LOCK(mc_platform->quit_lock);
00353 while (mc_platform->connection_queue->size == 0 && !mc_platform->quit) {
00354 MUTEX_UNLOCK(mc_platform->quit_lock);
00355 COND_WAIT(
00356 mc_platform->connection_queue->cond,
00357 mc_platform->connection_queue->lock
00358 );
00359 MUTEX_LOCK(mc_platform->quit_lock);
00360 }
00361 if 
00362 (
00363 mc_platform->connection_queue->size == 0 &&
00364 mc_platform->quit
00365 )
00366 {
00367 MUTEX_UNLOCK(mc_platform->quit_lock);
00368 MUTEX_UNLOCK(mc_platform->connection_queue->lock);
00369 return 0;
00370 }
00371 MUTEX_UNLOCK(mc_platform->quit_lock);
00372 MUTEX_UNLOCK(mc_platform->connection_queue->lock);
00373 /* Send MC Signal */
00374 MUTEX_LOCK(mc_platform->MC_signal_lock);
00375 mc_platform->MC_signal = MC_RECV_CONNECTION;
00376 COND_BROADCAST(mc_platform->MC_signal_cond);
00377 MUTEX_UNLOCK(mc_platform->MC_signal_lock);
00378 
00379 /* Check the giant lock to make sure we can continue */
00380 MUTEX_LOCK(mc_platform->giant_lock);
00381 while (mc_platform->giant == 0) {
00382 COND_WAIT(
00383 mc_platform->giant_cond,
00384 mc_platform->giant_lock
00385 );
00386 }
00387 MUTEX_UNLOCK(mc_platform->giant_lock);
00388 
00389 /* Continue with normal operation */
00390 connection = connection_queue_Pop(mc_platform->connection_queue);
00391 mtp_http = mtp_http_New();
00392 if ( mtp_http_InitializeFromConnection(mtp_http, connection ) )
00393 {
00394 connection_Destroy(connection);
00395 mtp_http_Destroy(mtp_http);
00396 continue;
00397 }
00398 
00399 switch(mtp_http->http_performative)
00400 {
00401 case HTTP_POST:
00402 case HTTP_PUT:
00403 /* See if the incoming message is going to any of our services. */
00404 /* See if it is a message for the AMS */
00405 if(
00406 !strcmp(mtp_http->target, "/ams") ||
00407 !strcmp( strrchr(mtp_http->target, (int)'/'), "/ams" )
00408 ) {
00409 message = message_New();
00410 /*message->message_parts = mtp_http->message_parts;*/
00411 message->message_body = (char*)malloc
00412 (
00413 sizeof(char) * 
00414 (strlen((char*)mtp_http->content->data)+1)
00415 );
00416 strcpy(message->message_body, (char*)mtp_http->content->data);
00417 message->xml_root = mxmlLoadString
00418 (
00419 NULL,
00420 message->message_body,
00421 MXML_NO_CALLBACK
00422 );
00423 if(message_xml_parse(message)) {
00424 fprintf(stderr, "Error parsing message. %s:%d\n",
00425 __FILE__,__LINE__);
00426 message_Destroy(message);
00427 mtp_http_Destroy(mtp_http);
00428 continue;
00429 }
00430 mtp_http_Destroy(mtp_http);
00431 break;
00432 } else if 
00433 ( 
00434 !strcmp(mtp_http->target, "/acc") ||
00435 !strcmp( strrchr(mtp_http->target, (int)'/'), "/acc")
00436 ) {
00437 /* Make sure there are two parts to the html message.
00438  * We expect to receive an xml envelope with a message attached. */
00439 if (mtp_http->message_parts != 2) {
00440 fprintf(stderr, "Error parsing message. %s:%d\n",
00441 __FILE__,__LINE__);
00442 mtp_http_Destroy(mtp_http);
00443 continue;
00444 }
00445 /* Now we need to parse the envelope */
00446 fipa_envelope = fipa_acl_envelope_New();
00447 err = fipa_envelope_Parse(fipa_envelope, (char*)mtp_http->content[0].data);
00448 if (err) {
00449 fprintf(stderr, "Error parsing message. %s:%d\n",
00450 __FILE__, __LINE__);
00451 fipa_acl_envelope_Destroy(fipa_envelope);
00452 mtp_http_Destroy(mtp_http);
00453 continue;
00454 }
00455 /* Now we need to check the envelope receivers and put copies of the message into
00456  * each receiving agent's mailbox. */
00457 for(i = 0; i < fipa_envelope->num_params; i++) {
00458 for(j = 0; j < fipa_envelope->params[i]->to->num; j++) {
00459 agent = agent_queue_SearchName(
00460 mc_platform->agent_queue,
00461 fipa_envelope->params[i]->to->fipa_agent_identifiers[j]->name
00462 );
00463 if (agent != NULL) {
00464 /* Parse, copy, and deliver the message to the agent. */
00465 fipa_message_string = fipa_message_string_New();
00466 fipa_message_string->message = strdup((char*)mtp_http->content[1].data);
00467 fipa_message_string->parse = fipa_message_string->message;
00468 fipa_message = fipa_acl_message_New();
00469 err = fipa_acl_Parse(fipa_message, fipa_message_string);
00470 if (err) {
00471 fipa_message_string_Destroy(fipa_message_string);
00472 fipa_acl_message_Destroy(fipa_message);
00473 fipa_acl_envelope_Destroy(fipa_envelope);
00474 mtp_http_Destroy(mtp_http);
00475 continue;
00476 }
00477 agent_mailbox_Post( agent->mailbox, fipa_message);
00478 fipa_message_string_Destroy(fipa_message_string);
00479 }
00480 }
00481 }
00482 fipa_acl_envelope_Destroy(fipa_envelope);
00483 mtp_http_Destroy(mtp_http);
00484 continue;
00485 }
00486 else {
00487 /* FIXME: We don't support other recipients yet */
00488 fprintf(stderr, "Unsupported. %s:%d\n", __FILE__, __LINE__);
00489 mtp_http_Destroy(mtp_http);
00490 }
00491 default:
00492 fprintf(stderr, "unsupported http performative. %s:%d\n",
00493 __FILE__, __LINE__);
00494 }
00495 
00496 /* If we get here, then we have an incoming message for the ams */
00497 connection_Destroy(connection);
00498 switch(message->message_type) {
00499 case RELAY:
00500 case REQUEST:
00501 case SUBSCRIBE:
00502 case CANCEL:
00503 case N_UNDRSTD:
00504 case MOBILE_AGENT:
00505 case QUER_IF:
00506 case QUER_REF:
00507 case AGENT_UPDATE:
00508 case RETURN_MSG:
00509 case FIPA_ACL:
00510 message_queue_Add(mc_platform->message_queue, message);
00511 break;
00512 #ifdef MC_SECURITY
00513 case ENCRYPTED_DATA:
00514 case ENCRYPTION_INITIALIZE:
00515 if (mc_platform->enable_security) {
00516 message_queue_Add(mc_platform->asm_message_queue, message);
00517 } else {
00518 WARN("MC Security not enabled. Discarding message...");
00519 message_Destroy(message);
00520 }
00521 break;
00522 case REQUEST_ENCRYPTION_INITIALIZE:
00523 if (mc_platform->enable_security) {
00524 message_queue_Add(mc_platform->message_queue, message);
00525 } else {
00526 WARN("MC Security not enabled. Discarding message...");
00527 message_Destroy(message);
00528 }
00529 break;
00530 #endif
00531 default:
00532 fprintf(stderr, "Unknown message type:%d. Rejecting message.%s:%d\n",
00533 message->message_type,
00534 __FILE__, __LINE__ );
00535 free(message);
00536 break;
00537 }
00538 }
00539 }
00540 
00541 void
00542 acc_Start(mc_platform_p mc_platform)
00543 {
00544 acc_p acc = mc_platform->acc;
00545 #ifndef _WIN32
00546 pthread_attr_t attr;
00547 pthread_attr_init(&attr);
00548 if(mc_platform->stack_size[MC_THREAD_ACC] != -1) {
00549 pthread_attr_setstacksize
00550 (
00551 &attr,
00552 mc_platform->stack_size[MC_THREAD_ACC]
00553 );
00554 }
00555 #else
00556 int stack_size;
00557 if (mc_platform->stack_size[MC_THREAD_ACC] < 1) {
00558 /* In windows, 0 is default, not min */
00559 stack_size = mc_platform->stack_size[MC_THREAD_ACC]+1; 
00560 } else {
00561 stack_size = mc_platform->stack_size[MC_THREAD_ACC];
00562 }
00563 #endif
00564 THREAD_CREATE
00565 ( 
00566 &acc->thread,
00567 acc_Thread,
00568 mc_platform 
00569 );
00570 THREAD_CREATE
00571 ( 
00572 &acc->message_handler_thread,
00573 acc_MessageHandlerThread,
00574 mc_platform
00575 );
00576 THREAD_CREATE
00577 (
00578 &acc->listen_thread,
00579 listen_Thread,
00580 mc_platform 
00581 );
00582 }
00583 
00584 #ifndef _WIN32
00585 void*
00586 listen_Thread(void* arg)
00587 #else
00588 DWORD WINAPI
00589 listen_Thread( LPVOID arg )
00590 #endif
00591 {
00592 #ifndef _WIN32
00593 int connectionsockfd; 
00594 int sockfd;
00595 struct sockaddr_in sktin;
00596 struct sockaddr_in peer_addr;
00597 #else
00598 SOCKET connectionsockfd;
00599 SOCKET sockfd;
00600 struct sockaddr_in sktin;
00601 struct sockaddr_in peer_addr;
00602 #endif
00603 
00604 connection_p connection;
00605 u_long connection_number;
00606 int connectionlen;
00607 mc_platform_p mc_platform = (mc_platform_p)arg;
00608 
00609 /* basic initialization */
00610 connection_number = 0;
00611 
00612 connectionlen = sizeof(struct sockaddr_in);
00613 
00614 /* Set up the socket */
00615 sockfd = socket(PF_INET, SOCK_STREAM, 0);
00616 sktin.sin_family = AF_INET;
00617 sktin.sin_port = htons(mc_platform->port);
00618 sktin.sin_addr.s_addr = INADDR_ANY;
00619 memset(sktin.sin_zero, '0円', sizeof sktin.sin_zero);
00620 if (bind(sockfd, (struct sockaddr *)&sktin, sizeof(struct sockaddr))
00621 == -1) {
00622 fprintf(stderr, "bind() error. %s:%d\n",
00623 __FILE__, __LINE__ );
00624 exit(1);
00625 }
00626 listen(sockfd, BACKLOG);
00627 
00628 /* this while loop runs continuously creating connections */
00629 while(1)
00630 {
00631 /* Set waiting flag */
00632 MUTEX_LOCK(mc_platform->acc->waiting_lock);
00633 mc_platform->acc->waiting = 1;
00634 COND_BROADCAST(mc_platform->acc->waiting_cond);
00635 MUTEX_UNLOCK(mc_platform->acc->waiting_lock);
00636 #ifndef _WIN32
00637 if((connectionsockfd = accept(sockfd, 
00638 (struct sockaddr *)&peer_addr, 
00639 (socklen_t *)&connectionlen)) < 0)
00640 #else
00641 if((connectionsockfd = accept(sockfd,
00642 (struct sockaddr *)&peer_addr,
00643 (int*)&connectionlen)) == INVALID_SOCKET)
00644 #endif
00645 {
00646 fprintf(stderr, "ListenThread: accept error \n");
00647 #ifdef _WIN32
00648 printf("Error number: %d\n", WSAGetLastError() );
00649 continue;
00650 #endif
00651 continue;
00652 }
00653 else 
00654 {
00655 /* Set waiting flag */
00656 MUTEX_LOCK(mc_platform->acc->waiting_lock);
00657 mc_platform->acc->waiting = 0;
00658 COND_BROADCAST(mc_platform->acc->waiting_cond);
00659 MUTEX_UNLOCK(mc_platform->acc->waiting_lock);
00660 /* create a new connection and insert it into the connection linked 
00661  * list */
00662 connection = (connection_p)malloc(sizeof(connection_t));
00663 CHECK_NULL(connection, exit(0););
00664 connection->connect_id = rand();
00665 connection->remote_hostname = NULL;
00666 connection->addr = peer_addr;
00667 connection->serverfd = sockfd;
00668 connection->clientfd = connectionsockfd;
00669 
00670 /* add the connection to list and increment the number of connections */
00671 connection_queue_Add(mc_platform->connection_queue, connection);
00672 }
00673 }
00674 
00675 /* Free the current thread */
00676 #ifndef _WIN32
00677 pthread_exit(0);
00678 #else
00679 ExitThread(0);
00680 #endif
00681 
00682 return 0;
00683 }

Generated on Tue Oct 28 17:03:22 2008 for Mobile-C by doxygen 1.5.5

AltStyle によって変換されたページ (->オリジナル) /