コード例 #1
0
car_timestamp_sender::~car_timestamp_sender() {
	cleanup_thread();
	cleanup_socket();
	cleanup_wsa();

	timeEndPeriod(1);
}
コード例 #2
0
ファイル: kill.c プロジェクト: WASSUM/longene_travel
/* destroy a thread when its refcount is 0 */
void destroy_thread(struct object *obj)
{
	struct w32thread *thread = (struct w32thread *)obj;

	ktrace("%p\n", obj);
	cleanup_thread(thread);
	release_object(thread->process);
	if (thread->token)
		release_object(thread->token);
}
コード例 #3
0
ファイル: server_handle.c プロジェクト: deepakagg/game-server
void * main_thread(void * data)
{
	int flag=1,choice,n;
	int temp;
	TCPsocket client_socket,server_socket;
	if(!intialize_thread())
	{
		printf("\n Therer is some error while initializing thread");
		return 0;
	 }
	printf("\n Value of active ports is:%d",get_active_threads());

	// first server receive request from client to connect and open master server socket. To be created only once.-permanent 
	if(common_connect_server(&host_ipaddress,&server_socket,global_port,(const char *)NULL)==0)
		return (void *)1;
	while(quit) 
	{
		// Open client socket on server side for sending dynamic port address-temprary
		if((client_socket=SDLNet_TCP_Accept(server_socket)))
		{
 			// send port address to client
			pthread_mutex_lock(&mutex_variable);
			printf("\n Value of active ports:%d",get_active_threads());
			if(get_active_threads()==0)
			{
				int temp=0;
				SDLNet_TCP_Send(client_socket,&(temp),2);
				SDLNet_TCP_Close(client_socket);
				pthread_mutex_unlock(&mutex_variable);
			}
			else
				if(SDLNet_TCP_Send(client_socket,&(thread_header->client.port),2)==2)
				{
					printf("\nNew Port is send to client"); 
					// close temprary client socket 
					SDLNet_TCP_Close(client_socket);
					// opening port so that server can accept content from client in different thread;
					pthread_mutex_unlock(&mutex_variable);
					printf("\n Activating thread");
					activate_thread();
				}
		}
	}
		printf("\nEverything is OK now exiting");	
		SDLNet_TCP_Close(server_socket);
		cleanup_thread();
		return NULL;
}
コード例 #4
0
static void cleanup(void)
{
	LOG("Cleaning up . . .\n");

	int i = 0;
	while (i < NUM_SENSORS) {
		cleanup_thread(i);
		i++;
	}

	LOG("Cleaned!\n");

	LOG("** SensorEmulationClientServer - Exited **\n");

	putchar('\n');
	exit(0);
}
コード例 #5
0
ファイル: thread.cpp プロジェクト: lvous/hadesmem
void TestThisThread()
{
  hadesmem::Thread thread(::GetCurrentThreadId());
  BOOST_TEST_EQ(thread, thread);
  hadesmem::Thread thread_new(::GetCurrentThreadId());
  BOOST_TEST_EQ(thread, thread_new);
  hadesmem::Thread const thread_moved(std::move(thread_new));
  hadesmem::Thread thread_copy(thread);
  BOOST_TEST_EQ(thread_copy, thread);
  thread = thread_copy;
  BOOST_TEST_EQ(thread, thread_copy);
  thread_new = std::move(thread_copy);
  BOOST_TEST_EQ(thread, thread_new);
  BOOST_TEST(thread >= thread);
  BOOST_TEST(thread <= thread);
  BOOST_TEST_EQ(thread.GetId(), ::GetCurrentThreadId());
  std::stringstream thread_str_1;
  thread_str_1.imbue(std::locale::classic());
  thread_str_1 << thread;
  DWORD thread_id_1;
  thread_str_1 >> thread_id_1;
  BOOST_TEST_EQ(thread.GetId(), thread_id_1);
  std::wstringstream thread_str_2;
  thread_str_2.imbue(std::locale::classic());
  thread_str_2 << thread;
  DWORD thread_id_2;
  thread_str_2 >> thread_id_2;
  BOOST_TEST_EQ(thread.GetId(), thread_id_2);

  hadesmem::detail::SmartHandle quit_event(
    ::CreateEvent(nullptr, TRUE, FALSE, nullptr));
  DWORD other_id = 0;
  hadesmem::detail::SmartHandle wait_thread(
    ::CreateThread(nullptr, 0, &WaitFunc, &quit_event, 0, &other_id));
  // Disgusting hack to work around a potential race condition where we suspend
  // the thread before it's actually waiting on our event, and instead it's
  // still in its initialization routine and ends up holding a lock that the
  // main thread will need (e.g. from malloc). See thread_140224_144550.dmp.
  ::Sleep(5 * 1000);
  auto const cleanup_thread_func = [&]()
  {

    BOOST_TEST_NE(::SetEvent(quit_event.GetHandle()), 0);
    BOOST_TEST_EQ(::WaitForSingleObject(wait_thread.GetHandle(), INFINITE),
                  WAIT_OBJECT_0);
  };
  {
    ScopeExit<decltype(cleanup_thread_func)> cleanup_thread(
      cleanup_thread_func);

    hadesmem::Thread const other_thread(other_id);
    BOOST_TEST_EQ(hadesmem::SuspendThread(other_thread), 0UL);
    BOOST_TEST_EQ(hadesmem::SuspendThread(other_thread), 1UL);
    BOOST_TEST_EQ(hadesmem::ResumeThread(other_thread), 2UL);
    BOOST_TEST_EQ(hadesmem::ResumeThread(other_thread), 1UL);

    {
      hadesmem::SuspendedThread const suspend_thread(other_thread.GetId());

      CONTEXT const full_context =
        hadesmem::GetThreadContext(other_thread, CONTEXT_FULL);
      CONTEXT const all_context =
        hadesmem::GetThreadContext(other_thread, CONTEXT_ALL);
      hadesmem::SetThreadContext(other_thread, full_context);
      hadesmem::SetThreadContext(other_thread, all_context);
      BOOST_TEST_THROWS(hadesmem::GetThreadContext(thread, CONTEXT_FULL),
                        hadesmem::Error);
    }

    {
      hadesmem::SuspendedProcess const suspend_process(::GetCurrentProcessId());
    }
  }
}
コード例 #6
0
ファイル: child.c プロジェクト: Distrotech/httpd
void child_main(apr_pool_t *pconf)
{
    apr_status_t status;
    apr_hash_t *ht;
    ap_listen_rec *lr;
    HANDLE child_events[2];
    HANDLE *child_handles;
    int listener_started = 0;
    int threads_created = 0;
    int watch_thread;
    int time_remains;
    int cld;
    unsigned tid;
    int rv;
    int i;

    apr_pool_create(&pchild, pconf);
    apr_pool_tag(pchild, "pchild");

    ap_run_child_init(pchild, ap_server_conf);
    ht = apr_hash_make(pchild);

    /* Initialize the child_events */
    max_requests_per_child_event = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (!max_requests_per_child_event) {
        ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf,
                     "Child %lu: Failed to create a max_requests event.", my_pid);
        exit(APEXIT_CHILDINIT);
    }
    child_events[0] = exit_event;
    child_events[1] = max_requests_per_child_event;

    allowed_globals.jobsemaphore = CreateSemaphore(NULL, 0, 1000000, NULL);
    apr_thread_mutex_create(&allowed_globals.jobmutex,
                            APR_THREAD_MUTEX_DEFAULT, pchild);

    /*
     * Wait until we have permission to start accepting connections.
     * start_mutex is used to ensure that only one child ever
     * goes into the listen/accept loop at once.
     */
    status = apr_proc_mutex_lock(start_mutex);
    if (status != APR_SUCCESS) {
        ap_log_error(APLOG_MARK,APLOG_ERR, status, ap_server_conf,
                     "Child %lu: Failed to acquire the start_mutex. Process will exit.", my_pid);
        exit(APEXIT_CHILDINIT);
    }
    ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf,
                 "Child %lu: Acquired the start mutex.", my_pid);

    /*
     * Create the worker thread dispatch IOCompletionPort
     * on Windows NT/2000
     */
    if (use_acceptex) {
        /* Create the worker thread dispatch IOCP */
        ThreadDispatchIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE,
                                                    NULL,
                                                    0,
                                                    0); /* CONCURRENT ACTIVE THREADS */
        apr_thread_mutex_create(&qlock, APR_THREAD_MUTEX_DEFAULT, pchild);
        qwait_event = CreateEvent(NULL, TRUE, FALSE, NULL);
        if (!qwait_event) {
            ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf,
                         "Child %lu: Failed to create a qwait event.", my_pid);
            exit(APEXIT_CHILDINIT);
        }
    }

    /*
     * Create the pool of worker threads
     */
    ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf,
                 "Child %lu: Starting %d worker threads.", my_pid, ap_threads_per_child);
    child_handles = (HANDLE) apr_pcalloc(pchild, ap_threads_per_child * sizeof(HANDLE));
    apr_thread_mutex_create(&child_lock, APR_THREAD_MUTEX_DEFAULT, pchild);

    while (1) {
        for (i = 0; i < ap_threads_per_child; i++) {
            int *score_idx;
            int status = ap_scoreboard_image->servers[0][i].status;
            if (status != SERVER_GRACEFUL && status != SERVER_DEAD) {
                continue;
            }
            ap_update_child_status_from_indexes(0, i, SERVER_STARTING, NULL);
            child_handles[i] = (HANDLE) _beginthreadex(NULL, (unsigned)ap_thread_stacksize,
                                                       worker_main, (void *) i, 0, &tid);
            if (child_handles[i] == 0) {
                ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf,
                             "Child %lu: _beginthreadex failed. Unable to create all worker threads. "
                             "Created %d of the %d threads requested with the ThreadsPerChild configuration directive.",
                             my_pid, threads_created, ap_threads_per_child);
                ap_signal_parent(SIGNAL_PARENT_SHUTDOWN);
                goto shutdown;
            }
            threads_created++;
            /* Save the score board index in ht keyed to the thread handle. We need this
             * when cleaning up threads down below...
             */
            apr_thread_mutex_lock(child_lock);
            score_idx = apr_pcalloc(pchild, sizeof(int));
            *score_idx = i;
            apr_hash_set(ht, &child_handles[i], sizeof(HANDLE), score_idx);
            apr_thread_mutex_unlock(child_lock);
        }
        /* Start the listener only when workers are available */
        if (!listener_started && threads_created) {
            create_listener_thread();
            listener_started = 1;
            winnt_mpm_state = AP_MPMQ_RUNNING;
        }
        if (threads_created == ap_threads_per_child) {
            break;
        }
        /* Check to see if the child has been told to exit */
        if (WaitForSingleObject(exit_event, 0) != WAIT_TIMEOUT) {
            break;
        }
        /* wait for previous generation to clean up an entry in the scoreboard */
        apr_sleep(1 * APR_USEC_PER_SEC);
    }

    /* Wait for one of three events:
     * exit_event:
     *    The exit_event is signaled by the parent process to notify
     *    the child that it is time to exit.
     *
     * max_requests_per_child_event:
     *    This event is signaled by the worker threads to indicate that
     *    the process has handled MaxRequestsPerChild connections.
     *
     * TIMEOUT:
     *    To do periodic maintenance on the server (check for thread exits,
     *    number of completion contexts, etc.)
     *
     * XXX: thread exits *aren't* being checked.
     *
     * XXX: other_child - we need the process handles to the other children
     *      in order to map them to apr_proc_other_child_read (which is not
     *      named well, it's more like a_p_o_c_died.)
     *
     * XXX: however - if we get a_p_o_c handle inheritance working, and
     *      the parent process creates other children and passes the pipes
     *      to our worker processes, then we have no business doing such
     *      things in the child_main loop, but should happen in master_main.
     */
    while (1) {
#if !APR_HAS_OTHER_CHILD
        rv = WaitForMultipleObjects(2, (HANDLE *) child_events, FALSE, INFINITE);
        cld = rv - WAIT_OBJECT_0;
#else
        rv = WaitForMultipleObjects(2, (HANDLE *) child_events, FALSE, 1000);
        cld = rv - WAIT_OBJECT_0;
        if (rv == WAIT_TIMEOUT) {
            apr_proc_other_child_refresh_all(APR_OC_REASON_RUNNING);
        }
        else
#endif
            if (rv == WAIT_FAILED) {
            /* Something serious is wrong */
            ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf,
                         "Child %lu: WAIT_FAILED -- shutting down server", my_pid);
            break;
        }
        else if (cld == 0) {
            /* Exit event was signaled */
            ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf,
                         "Child %lu: Exit event signaled. Child process is ending.", my_pid);
            break;
        }
        else {
            /* MaxRequestsPerChild event set by the worker threads.
             * Signal the parent to restart
             */
            ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf,
                         "Child %lu: Process exiting because it reached "
                         "MaxRequestsPerChild. Signaling the parent to "
                         "restart a new child process.", my_pid);
            ap_signal_parent(SIGNAL_PARENT_RESTART);
            break;
        }
    }

    /*
     * Time to shutdown the child process
     */

 shutdown:

    winnt_mpm_state = AP_MPMQ_STOPPING;
    /* Setting is_graceful will cause threads handling keep-alive connections
     * to close the connection after handling the current request.
     */
    is_graceful = 1;

    /* Close the listening sockets. Note, we must close the listeners
     * before closing any accept sockets pending in AcceptEx to prevent
     * memory leaks in the kernel.
     */
    for (lr = ap_listeners; lr ; lr = lr->next) {
        apr_socket_close(lr->sd);
    }

    /* Shutdown listener threads and pending AcceptEx socksts
     * but allow the worker threads to continue consuming from
     * the queue of accepted connections.
     */
    shutdown_in_progress = 1;

    Sleep(1000);

    /* Tell the worker threads to exit */
    workers_may_exit = 1;

    /* Release the start_mutex to let the new process (in the restart
     * scenario) a chance to begin accepting and servicing requests
     */
    rv = apr_proc_mutex_unlock(start_mutex);
    if (rv == APR_SUCCESS) {
        ap_log_error(APLOG_MARK,APLOG_NOTICE, rv, ap_server_conf,
                     "Child %lu: Released the start mutex", my_pid);
    }
    else {
        ap_log_error(APLOG_MARK,APLOG_ERR, rv, ap_server_conf,
                     "Child %lu: Failure releasing the start mutex", my_pid);
    }

    /* Shutdown the worker threads */
    if (!use_acceptex) {
        for (i = 0; i < threads_created; i++) {
            add_job(INVALID_SOCKET);
        }
    }
    else { /* Windows NT/2000 */
        /* Post worker threads blocked on the ThreadDispatch IOCompletion port */
        while (g_blocked_threads > 0) {
            ap_log_error(APLOG_MARK,APLOG_INFO, APR_SUCCESS, ap_server_conf,
                         "Child %lu: %d threads blocked on the completion port", my_pid, g_blocked_threads);
            for (i=g_blocked_threads; i > 0; i--) {
                PostQueuedCompletionStatus(ThreadDispatchIOCP, 0, IOCP_SHUTDOWN, NULL);
            }
            Sleep(1000);
        }
        /* Empty the accept queue of completion contexts */
        apr_thread_mutex_lock(qlock);
        while (qhead) {
            CloseHandle(qhead->Overlapped.hEvent);
            closesocket(qhead->accept_socket);
            qhead = qhead->next;
        }
        apr_thread_mutex_unlock(qlock);
    }

    /* Give busy threads a chance to service their connections,
     * (no more than the global server timeout period which 
     * we track in msec remaining).
     */
    watch_thread = 0;
    time_remains = (int)(ap_server_conf->timeout / APR_TIME_C(1000));

    while (threads_created)
    {
        int nFailsafe = MAXIMUM_WAIT_OBJECTS;
        DWORD dwRet;

        /* Every time we roll over to wait on the first group
         * of MAXIMUM_WAIT_OBJECTS threads, take a breather,
         * and infrequently update the error log.
         */
        if (watch_thread >= threads_created) {
            if ((time_remains -= 100) < 0)
                break;

            /* Every 30 seconds give an update */
            if ((time_remains % 30000) == 0) {
                ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, 
                             ap_server_conf,
                             "Child %lu: Waiting %d more seconds "
                             "for %d worker threads to finish.", 
                             my_pid, time_remains / 1000, threads_created);
            }
            /* We'll poll from the top, 10 times per second */
            Sleep(100);
            watch_thread = 0;
        }

        /* Fairness, on each iteration we will pick up with the thread
         * after the one we just removed, even if it's a single thread.
         * We don't block here.
         */
        dwRet = WaitForMultipleObjects(min(threads_created - watch_thread,
                                           MAXIMUM_WAIT_OBJECTS),
                                       child_handles + watch_thread, 0, 0);

        if (dwRet == WAIT_FAILED) {
            break;
        }
        if (dwRet == WAIT_TIMEOUT) {
            /* none ready */
            watch_thread += MAXIMUM_WAIT_OBJECTS;
            continue;
        }
        else if (dwRet >= WAIT_ABANDONED_0) {
            /* We just got the ownership of the object, which
             * should happen at most MAXIMUM_WAIT_OBJECTS times.
             * It does NOT mean that the object is signaled.
             */
            if ((nFailsafe--) < 1)
                break;
        }
        else {
            watch_thread += (dwRet - WAIT_OBJECT_0);
            if (watch_thread >= threads_created)
                break;
            cleanup_thread(child_handles, &threads_created, watch_thread);
        }
    }
 
    /* Kill remaining threads off the hard way */
    if (threads_created) {
        ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf,
                     "Child %lu: Terminating %d threads that failed to exit.",
                     my_pid, threads_created);
    }
    for (i = 0; i < threads_created; i++) {
        int *score_idx;
        TerminateThread(child_handles[i], 1);
        CloseHandle(child_handles[i]);
        /* Reset the scoreboard entry for the thread we just whacked */
        score_idx = apr_hash_get(ht, &child_handles[i], sizeof(HANDLE));
        if (score_idx) {
            ap_update_child_status_from_indexes(0, *score_idx,
                                                SERVER_DEAD, NULL);
        }
    }
    ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf,
                 "Child %lu: All worker threads have exited.", my_pid);

    CloseHandle(allowed_globals.jobsemaphore);
    apr_thread_mutex_destroy(allowed_globals.jobmutex);
    apr_thread_mutex_destroy(child_lock);

    if (use_acceptex) {
        apr_thread_mutex_destroy(qlock);
        CloseHandle(qwait_event);
    }

    apr_pool_destroy(pchild);
    CloseHandle(exit_event);
}
コード例 #7
0
static void *client_to_remote_server(void *arg)
{
	struct client_to_rs_data *r = arg;

	char ip[sizeof("xxx:xxx:xxx:xxx")] = "0.0.0.0";
	int rs_port = r->rs_port;
	int n = r->num;

	LOG1_THREAD("** Client for %s meant for getting readings from a remote server - Started! **\n", sensors_name[n]);

	const char *rs_ip_port_file = REMOTE_SERVER_IP_PORT_CONF_FILE;
	FILE *rs_ip_port_fp = fopen(rs_ip_port_file, "r");
	if (rs_ip_port_fp) {
		LOG1_THREAD("Reading remote server ip and port from %s\n", rs_ip_port_file);

		bool fine = fscanf(rs_ip_port_fp, "%s", ip) == 1;
		if (!fine) {
			ERR1_THREAD("Something probably wrong with remote server ip or port - fscanf - %s\n", strerror(errno));
			goto done;
		}
		fgetc(rs_ip_port_fp); // Skip space

		fclose(rs_ip_port_fp);
		rs_ip_port_fp = NULL;
	} else {
		ERR1_THREAD("Failed to read %s. fopen - %s\n", rs_ip_port_file, strerror(errno));
		goto done;
	}

	struct sockaddr_in serv_addr = { 0, };
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(rs_port);
	
	LOG1_THREAD("Converting remote server ip . . .\n");
	LOG1_THREAD("Remote server port: %d\n", rs_port);
	int af = AF_INET;
	int convert_ret = inet_pton(af, ip, &serv_addr.sin_addr);
	bool invalid_ip_str = convert_ret == 0;
	bool invalid_af_family = convert_ret == -1;
	if (invalid_ip_str) {
		ERR1_THREAD("Invalid ip str - %s\n", ip);
		goto done;
	} else if(invalid_af_family) {
		ERR1_THREAD("Invalid af family - %d\n", af);
		goto done;
	}
	LOG1_THREAD("Given remote server ip(%s) converted . . .\n", ip);

	strcpy(ip, LOCALHOST_IP);
	int emu_port = r->emu_port;

	free(r);
	r = NULL;
	
	struct sockaddr_in client_addr = { 0, };
	client_addr.sin_family = AF_INET;
	client_addr.sin_port = htons(emu_port);
	
	LOG1_THREAD("Converting emu ip . . .\n");
	LOG1_THREAD("Emu port: %d\n", emu_port);
	convert_ret = inet_pton(af, ip, &client_addr.sin_addr);
	invalid_ip_str = convert_ret == 0;
	invalid_af_family = convert_ret == -1;
	if (invalid_ip_str) {
		ERR1_THREAD("Invalid ip str - %s\n", ip);
		goto done;
	} else if(invalid_af_family) {
		ERR1_THREAD("Invalid af family - %d\n", af);
		goto done;
	}
	LOG1_THREAD("Given emulator ip(%s) converted . . .\n", ip);
	
	while (1) {
		if (client_to_rs_sockfd[n] != -1) {
			LOG1_THREAD("Closing client to remote server socket . . .\n");
			close(client_to_rs_sockfd[n]);
			client_to_rs_sockfd[n] = -1;
			LOG1_THREAD("Closed!\n");
		}

		LOG1_THREAD("Opening remote server socket . . .\n");
		client_to_rs_sockfd[n] = socket(AF_INET, SOCK_STREAM, 0);
		if (client_to_rs_sockfd[n] == -1) {
			ERR1_THREAD("Socket - %s\n", strerror(errno));
			goto done;
		}
		LOG1_THREAD("Remote server socket opened . . .\n");

		LOG1_THREAD("Connecting . . .\n");
		bool connected = connect(client_to_rs_sockfd[n], (struct sockaddr *)&serv_addr, sizeof(serv_addr)) != -1;
		if (!connected) {
			ERR1_THREAD("Connect - %s\n", strerror(errno));
			sleep(1);
			continue;
		}
		LOG1_THREAD("Connected . . .\n");

		if (emu_sockfd[n] != -1) {
			LOG1_THREAD("Closing emu socket . . .\n");
			close(emu_sockfd[n]);
			emu_sockfd[n] = -1;
			LOG1_THREAD("Closed!\n");
		}

		LOG1_THREAD("Opening emu socket . . .\n");
		emu_sockfd[n] = socket(AF_INET, SOCK_STREAM, 0);
		if (emu_sockfd[n] == -1) {
			ERR1_THREAD("socket - %s\n", strerror(errno));
			goto done;
		}
		LOG1_THREAD("Emu socket opened!\n");

		LOG1_THREAD("Connecting . . .\n");
		connected = connect(emu_sockfd[n], (struct sockaddr *)&client_addr, sizeof(client_addr)) != -1;
		if (!connected) {
			ERR1_THREAD("connect - %s\n", strerror(errno));
			goto done;
		}
		LOG1_THREAD("Connected!\n");

		time_t seed = time(NULL);
		if (seed == -1) {
			ERR1_THREAD("time - Failed to generate a seed - %s\n", strerror(errno));
			// Not a crtical error. So, we continue!
		}
		srand(seed);

		while (1) {
			size_t readings_size = n == EAccel ? ACCEL_READINGS_BUF_SIZE + 1 :
						n == EGyro ? GYRO_READINGS_BUF_SIZE + 1 : READINGS_BUF_SIZE + 1;

			char rs_readings[readings_size];
			memset(rs_readings, 0, sizeof(rs_readings));

			LOG1_THREAD("Receiving . . .\n");
			ssize_t bytes_received = recvfrom(client_to_rs_sockfd[n], rs_readings, readings_size, MSG_WAITALL, NULL, 0);
			if (bytes_received == -1) {
				ERR1_THREAD("recvFrom - %s\n", strerror(errno));
				break;
			}
			LOG1_THREAD("%zd bytes received!\n", bytes_received);
			LOG1_THREAD("Remote server readings: %s\n", rs_readings);

			LOG_READING;

			if (!bytes_received) {
				LOG1_THREAD("Seems like connection to remote server is lost. Will reconnect.\n");
				break;
			}

			if (bytes_received != readings_size) {
				LOG1_THREAD("Partial data. Ignoring\n");
				continue;
			}

			LOG1_THREAD("Sending to emulator via port redirection!\n");
			ssize_t bytes_sent = sendto(emu_sockfd[n], rs_readings, readings_size, 0, NULL, 0);
			if (bytes_sent == -1) {
				ERR1_THREAD("sendto - %s\n", strerror(errno));
				break;
			} else {
				LOG1_THREAD("%zd bytes wrote!\n", bytes_sent);
			}

			usleep(1000);
		}
	}

done:
	if (client_to_rs_sockfd[n] != -1) {
		close(client_to_rs_sockfd[n]);
		client_to_rs_sockfd[n] = -1;
	}

	LOG1_THREAD("** Client for %s meant for getting readings from a remote server - Terminated! **\n", sensors_name[n]);

	cleanup_thread(n);

	return 0;
}
コード例 #8
0
static void *dummy_server(void *args)
{
	struct dummy_server_data *d = args;
	int port = d->port;
	int n = d->num;

	LOG_DUMMY_S_THREAD("** Dummy server for %s on behalf of the emulator server - Started! **\n", sensors_name[n]);
	LOG_DUMMY_S_THREAD("** Port : %d\n", port);
	LOG_DUMMY_S_THREAD("** Server number : %d\n", n);
	free(d);
	d = NULL;
	
	struct sockaddr_in serv_addr = { 0 };

	LOG_DUMMY_S_THREAD("Opening socket . . .\n");
	dummy_server_listenfd[n] = socket(AF_INET, SOCK_STREAM, 0);
	if (dummy_server_listenfd[n] == -1) {
		ERR_DUMMY_S_THREAD("socket - Opening failed - %s\n", strerror(errno));
		goto done;
	}
	LOG_DUMMY_S_THREAD("Opened!\n");
	
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	serv_addr.sin_port = htons(port);

	LOG_DUMMY_S_THREAD("Binding socket . . .\n");
	bool bound = bind(dummy_server_listenfd[n], (struct sockaddr*)&serv_addr, sizeof(serv_addr)) != -1;
	if (!bound && errno != EADDRINUSE) { // Due to port mapping with Qemu, this bind
						// may return EADDRINUSE. We just have to ignore it!
		ERR_DUMMY_S_THREAD("bind - Failed - %s %d\n", strerror(errno), errno);
		goto done;
	}
	LOG_DUMMY_S_THREAD("Bound!\n");

	LOG_DUMMY_S_THREAD("Trying to listen . . .\n");
	bool listening = listen(dummy_server_listenfd[n], 10) != -1;
	if (!listening) {
		ERR_DUMMY_S_THREAD("listen - Failed - %s\n", strerror(errno));
		goto done;
	}
	LOG_DUMMY_S_THREAD("Listening!\n");

	LOG_DUMMY_S_THREAD("Accepting connection . . .\n");
	dummy_server_connfd[n] = accept(dummy_server_listenfd[n], (struct sockaddr*)NULL, NULL);
	if (dummy_server_connfd[n] == -1) {
		ERR_DUMMY_S_THREAD("accept - Failed - %s\n", strerror(errno));
		goto done;
	}
	LOG_DUMMY_S_THREAD("Accepted!\n");

	LOG_DUMMY_S_THREAD("Sleeping forever . . .\n");
	sem_t dummy_sem = { { 0 } };
	bool initzd = sem_init(&dummy_sem, 0, 0) != -1;
	if (!initzd) {
		ERR_DUMMY_S_THREAD("sem_init - Failed - %s\n", strerror(errno));
		goto done;
	}
	bool waited = sem_wait(&dummy_sem) != -1;
	if (!waited) {
		LOG_DUMMY_S_THREAD("Couldn't sleep forever!\n");
		LOG_DUMMY_S_THREAD("\n\n** CONTROL SHOULD NEVER REACH HERE!! **\n\n");
		LOG_DUMMY_S_THREAD("\n\n** HELP ME!! I'M LOST!\n");
		ERR_DUMMY_S_THREAD("sem_wait - Failed - %s\n", strerror(errno));
		goto done;
	}

done:
	cleanup_thread(n);

	LOG_DUMMY_S_THREAD("** Dummy server for %s on behalf of the emulator server - Terminated! **\n", sensors_name[n]);

	return NULL;
}