Esempio n. 1
0
File: db.c Progetto: jlsandell/Craft
int db_worker_run(void *arg) {
    int running = 1;
    while (running) {
        RingEntry e;
        mtx_lock(&mtx);
        while (!ring_get(&ring, &e)) {
            cnd_wait(&cnd, &mtx);
        }
        mtx_unlock(&mtx);
        switch (e.type) {
        case BLOCK:
            _db_insert_block(e.p, e.q, e.x, e.y, e.z, e.w);
            break;
        case KEY:
            _db_set_key(e.p, e.q, e.key);
            break;
        case COMMIT:
            _db_commit();
            break;
        case EXIT:
            running = 0;
            break;
        }
    }
    return 0;
}
Esempio n. 2
0
int cnd_timedwait_ms(cnd_t *cnd, mtx_t *mtx, int timeout_ms) {
  if (timeout_ms == -1 /* INFINITE*/)
    return cnd_wait(cnd, mtx);
#if defined(_TTHREAD_WIN32_)
	return _cnd_timedwait_win32(cnd, mtx, (DWORD)timeout_ms);
#else
  int ret;
	struct timeval tv;
	struct timespec ts;

	gettimeofday(&tv, NULL);
  ts.tv_sec = tv.tv_sec;
  ts.tv_nsec = tv.tv_usec * 1000;

	ts.tv_sec  += timeout_ms / 1000;
	ts.tv_nsec += (timeout_ms % 1000) * 1000000;

	if (ts.tv_nsec >= 1000000000) {
		ts.tv_sec++;
		ts.tv_nsec -= 1000000000;
	}

  ret = pthread_cond_timedwait(cnd, mtx, &ts);
  if (ret == ETIMEDOUT)
  {
    return thrd_timedout;
  }
  return ret == 0 ? thrd_success : thrd_error;
#endif
}
Esempio n. 3
0
static int
squash_stream_thread_func (SquashStream* stream) {
    assert (stream != NULL);

    SquashStreamPrivate* priv = stream->priv;
    SquashOperation operation;
    SquashCodec* codec = stream->codec;

    assert (priv != NULL);
    assert (codec != NULL);

    mtx_lock (&(priv->io_mtx));
    priv->result = SQUASH_OK;
    cnd_signal (&(priv->result_cnd));

    while ((operation = priv->request) == SQUASH_OPERATION_INVALID) {
        cnd_wait (&(priv->request_cnd), &(priv->io_mtx));
    }
    priv->request = SQUASH_OPERATION_INVALID;

    assert (codec->impl.splice != NULL);

    priv->result = codec->impl.splice (codec, stream->options, stream->stream_type, squash_stream_read_cb, squash_stream_write_cb, stream);
    if (priv->result == SQUASH_OK)
        priv->result = SQUASH_END_OF_STREAM;

    priv->finished = true;
    cnd_signal (&(priv->result_cnd));
    mtx_unlock (&(priv->io_mtx));

    return 0;
}
Esempio n. 4
0
/*
====================
TFile_StartServer
====================
*/
void TFile_StartServer( void ) {
	server_message_t message;

	if ( !server_initialized ) {
		T_FatalError( "TFile_StartServer: Server is not initialized" );
	}

	if ( server_running ) {
		T_FatalError( "TFile_StartServer: Server is already running" );
	}

	cnd_init( &server_condition );
	mtx_init( &server_mutex, mtx_plain );
	mtx_lock( &server_mutex );

	message.ip_socket = server_socket;
	message.ip6_socket = server_socket6;
	if ( thrd_create( &server_thread, ServerThread, &message ) != thrd_success ) {
		T_FatalError( "TFile_StartServer: Unable to create thread" );
	}

	cnd_wait( &server_condition, &server_mutex );

	mtx_destroy( &server_mutex );
	cnd_destroy( &server_condition );

	server_running = t_true;
}
Esempio n. 5
0
int sfgeWriteChannelBlocking( sfgeChannel channel, void *data, int size ) {
    sfgeChan chan;
    if( channel < channelCount ) {
        chan = channels[channel];
        mtx_lock(&chan.mutex);
        while( 1 ) {
            if( chan.writeIndex + size > CHAN_BUF_SIZE ) {
                /* Mark the size byte to indicate that we've wrapped around */
                ((char*)chan.data)[chan.writeIndex] = 0;
                chan.writeIndex = 0;
            }
            if( chan.writeIndex > chan.readIndex
             || chan.writeIndex + size < chan.readIndex ) {
                ((char*)chan.data)[chan.writeIndex] = (char)size;
                /* Plus 1 for the leading size byte */
                memcpy(chan.data+1, data, size);
                chan.writeIndex += size + 1;
                mtx_unlock(&chan.mutex);
                cnd_broadcast(&chan.readCond);
                return 1;
            }
            else {
                cnd_wait(&chan.writeCond, &chan.mutex);
            }
        }
    }
    else {
        printf("WARN: Attempted to read from non-existant channel: %d!\n",
               channel);
        return 0;
    }
}
int cnd_timedwait_abs (cnd_t *cnd, mtx_t *mtx, const struct timespec *tspec) {
        if (tspec->tv_sec == RD_POLL_INFINITE)
                return cnd_wait(cnd, mtx);
        else if (tspec->tv_sec == RD_POLL_NOWAIT)
                return thrd_timedout;

        return cnd_timedwait(cnd, mtx, tspec);
}
Esempio n. 7
0
int sfgeReadChannelBlocking( sfgeChannel channel, void *data, int size ) {
    char i;
    sfgeChan chan;
    if( channel < channelCount ) {
        chan = channels[channel];
        mtx_lock(&chan.mutex);
        while( 1 ) {
            if( chan.readIndex != chan.writeIndex ) {
                i = ((char*)chan.data)[chan.readIndex];
                /* First byte = size of message. If it's zero, then the writer has
                 * wrapped around. */
                if( i == 0 ) {
                    chan.readIndex = 0;
                    i = ((char*)chan.data)[chan.readIndex];
                    if( chan.readIndex != chan.writeIndex ) {
                        if( size == i ) {
                            memcpy(data, chan.data, size);
                            /* Plus one for the leading size byte */
                            chan.readIndex += size + 1;
                            mtx_unlock(&chan.mutex);
                            cnd_broadcast(&chan.writeCond);
                            return 1;
                        }
                        else {
                            /* If there's data in the pipe but the wrong struct
                             * passed in, then immediately return 0. */
                            mtx_unlock(&chan.mutex);
                            return 0;
                        }
                    }
                }
                else {
                    if( size == i ) {
                        memcpy(data, chan.data + chan.readIndex, size);
                        /* Plus one for the leading size byte */
                        chan.readIndex += size + 1;
                        mtx_unlock(&chan.mutex);
                        cnd_broadcast(&chan.writeCond);
                        return 1;
                    }
                    else {
                        /* If there's data in the pipe but the wrong struct
                         * passed in, then immediately return 0. */
                        mtx_unlock(&chan.mutex);
                        return 0;
                    }
                }
            }
            /* Read and write cursors met, no data to read. */
            cnd_wait(&chan.readCond, &chan.mutex);
        }
    }
    else {
        printf("WARN: Attempted to read from non-existant channel: %d!\n",
               channel);
        return 0;
    }
}
void Barrier2() {  
  __VERIFIER_atomic_acquire();
  count++;
  if (count == 3) {
    cnd_broadcast(COND); //pthread_cond_broadcast(&cond);
    count = 0; }
  else
    cnd_wait(COND,MTX); //pthread_cond_wait(&cond, &m);
  __VERIFIER_atomic_release(); }
Esempio n. 9
0
/**
 * @brief Initialize a stream.
 * @protected
 *
 * @warning This function must only be used to implement a subclass of
 * @ref SquashStream.  Streams returned by other functions will
 * already be initialized, and you *must* *not* call this function on
 * them; doing so will likely trigger a memory leak.
 *
 * @param stream The stream to initialize.
 * @param codec The codec to use.
 * @param stream_type The stream type.
 * @param options The options.
 * @param destroy_notify Function to call to destroy the instance.
 *
 * @see squash_object_init
 */
void
squash_stream_init (void* stream,
                    SquashCodec* codec,
                    SquashStreamType stream_type,
                    SquashOptions* options,
                    SquashDestroyNotify destroy_notify) {
    SquashStream* s;

    assert (stream != NULL);

    s = (SquashStream*) stream;

    squash_object_init (stream, false, destroy_notify);

    s->next_in = NULL;
    s->avail_in = 0;
    s->total_in = 0;

    s->next_out = NULL;
    s->avail_out = 0;
    s->total_out = 0;

    s->codec = codec;
    s->options = (options != NULL) ? squash_object_ref (options) : NULL;
    s->stream_type = stream_type;
    s->state = SQUASH_STREAM_STATE_IDLE;

    s->user_data = NULL;
    s->destroy_user_data = NULL;

    if (codec->impl.create_stream == NULL && codec->impl.splice != NULL) {
        s->priv = squash_malloc (sizeof (SquashStreamPrivate));

        mtx_init (&(s->priv->io_mtx), mtx_plain);
        mtx_lock (&(s->priv->io_mtx));

        s->priv->request = SQUASH_OPERATION_INVALID;
        cnd_init (&(s->priv->request_cnd));

        s->priv->result = SQUASH_STATUS_INVALID;
        cnd_init (&(s->priv->result_cnd));

        s->priv->finished = false;
#if !defined(NDEBUG)
        int res =
#endif
            thrd_create (&(s->priv->thread), (thrd_start_t) squash_stream_thread_func, s);
        assert (res == thrd_success);

        while (s->priv->result == SQUASH_STATUS_INVALID)
            cnd_wait (&(s->priv->result_cnd), &(s->priv->io_mtx));
        s->priv->result = SQUASH_STATUS_INVALID;
    } else {
        s->priv = NULL;
    }
}
Esempio n. 10
0
static rd_kafka_event_t *wait_background_event_cb (void) {
        rd_kafka_event_t *rkev;
        mtx_lock(&last_event_lock);
        while (!(rkev = last_event))
                cnd_wait(&last_event_cnd, &last_event_lock);
        last_event = NULL;
        mtx_unlock(&last_event_lock);

        return rkev;
}
COND_RESULT Condition_Wait(COND_HANDLE handle, LOCK_HANDLE lock, int timeout_milliseconds)
{
    COND_RESULT result;
    // Codes_SRS_CONDITION_18_004: [ Condition_Wait shall return COND_INVALID_ARG if handle is NULL ]
    // Codes_SRS_CONDITION_18_005: [ Condition_Wait shall return COND_INVALID_ARG if lock is NULL and timeout_milliseconds is 0 ]
    // Codes_SRS_CONDITION_18_006: [ Condition_Wait shall return COND_INVALID_ARG if lock is NULL and timeout_milliseconds is not 0 ]
    if (handle == NULL || lock == NULL)
    {
        result = COND_INVALID_ARG;
    }
    else
    {
        if (timeout_milliseconds > 0)
        {
            struct xtime tm;
            int wait_result;
            time_t now = get_time(NULL);

            // Codes_SRS_CONDITION_18_013: [ Condition_Wait shall accept relative timeouts ]
            tm.sec = (unsigned long)get_difftime(now, (time_t)0) + (timeout_milliseconds / 1000);
            tm.nsec = (timeout_milliseconds % 1000) * 1000000L;
            wait_result = cnd_timedwait((cnd_t *)handle, (mtx_t*)lock, &tm);
            if (wait_result == thrd_timedout)
            {
                // Codes_SRS_CONDITION_18_011: [ Condition_Wait shall return COND_TIMEOUT if the condition is NOT triggered and timeout_milliseconds is not 0 ]
                result = COND_TIMEOUT;
            }
            else if (wait_result == thrd_success)
            {
                // Codes_SRS_CONDITION_18_012: [ Condition_Wait shall return COND_OK if the condition is triggered and timeout_milliseconds is not 0 ]
                result = COND_OK;
            }
            else
            {
                LogError("Failed to Condition_Wait\r\n");
                result = COND_ERROR;
            }
        }
        else
        {
            if (cnd_wait((cnd_t*)handle, (mtx_t *)lock) != thrd_success)
            {
                LogError("Failed to cnd_wait\r\n");
                result = COND_ERROR;
            }
            else
            {
                // Codes_SRS_CONDITION_18_010: [ Condition_Wait shall return COND_OK if the condition is triggered and timeout_milliseconds is 0 ]
                result = COND_OK;
            }
        }
    }
    return result;
}
Esempio n. 12
0
int stack10_pop(Stack10 *s, int *x){
	mtx_lock(&s->mtx_);
	
	while(s->vused_ == 0){
		cnd_wait(&s->cnd_pop_, &s->mtx_);
	}
	*x = s->v_[--s->vused_];
	
	cnd_signal(&s->cnd_push_);
	mtx_unlock(&s->mtx_);
	return 0;
}
Esempio n. 13
0
int stack10_push(Stack10 *s, int x){
	mtx_lock(&s->mtx_);
	
	while(s->vused_ >= S_SIZE){
		cnd_wait(&s->cnd_push_, &s->mtx_);
	}
	s->v_[s->vused_++] = x;

	cnd_signal(&s->cnd_pop_);
	mtx_unlock(&s->mtx_);
	return 0;
}
Esempio n. 14
0
enum pipe_error util_ringbuffer_dequeue( struct util_ringbuffer *ring,
                                         struct util_packet *packet,
                                         unsigned max_dwords,
                                         boolean wait )
{
   const struct util_packet *ring_packet;
   unsigned i;
   int ret = PIPE_OK;

   /* XXX: over-reliance on mutexes, etc:
    */
   mtx_lock(&ring->mutex);

   /* Get next ring entry:
    */
   if (wait) {
      while (util_ringbuffer_empty(ring))
         cnd_wait(&ring->change, &ring->mutex);
   }
   else {
      if (util_ringbuffer_empty(ring)) {
         ret = PIPE_ERROR_OUT_OF_MEMORY;
         goto out;
      }
   }

   ring_packet = &ring->buf[ring->tail];

   /* Both of these are considered bugs.  Raise an assert on debug builds.
    */
   if (ring_packet->dwords > ring->mask + 1 - util_ringbuffer_space(ring) ||
       ring_packet->dwords > max_dwords) {
      assert(0);
      ret = PIPE_ERROR_BAD_INPUT;
      goto out;
   }

   /* Copy data from ring:
    */
   for (i = 0; i < ring_packet->dwords; i++) {
      packet[i] = ring->buf[ring->tail];
      ring->tail++;
      ring->tail &= ring->mask;
   }

out:
   /* Signal change:
    */
   cnd_signal(&ring->change);
   mtx_unlock(&ring->mutex);
   return ret;
}
Esempio n. 15
0
/* Thread function: Condition waiter */
static int thread_condition_waiter(void * aArg)
{
  (void)aArg;

  fflush(stdout);
  mtx_lock(&gMutex);
  while(gCount > 0)
  {
    fflush(stdout);
    cnd_wait(&gCond, &gMutex);
  }
  mtx_unlock(&gMutex);
  return 0;
}
Esempio n. 16
0
/* Thread function: Condition waiter */
int ThreadCondition2(void * aArg)
{
  printf(" Wating...");
  fflush(stdout);
  mtx_lock(&gMutex);
  while(gCount > 0)
  {
    printf(".");
    fflush(stdout);
    cnd_wait(&gCond, &gMutex);
  }
  printf(".\n");
  return 0;
}
Esempio n. 17
0
sfgeChannel sfgeRequireChannel( const char *id ) {
    int i;
    mtx_lock(&messengerLock);
    while( 1 ) {
        for( i = 0; i < channelCount; i++ ) {
            if( strcmp(id, channels[i].id) == 0 ) {
                mtx_unlock(&messengerLock);
                return i;
            }
        }
        /* If the channel is required, we simply block and check again on the
         * next channel registration. */
        cnd_wait(&requireCond, &messengerLock);
    }
    return -1;
}
Esempio n. 18
0
bool RWMutex::wrlock()
{
	bool result = true;
	if(mtx_lock(&mtxExclusiveAccess) != thrd_success)
		return false;

	if(mtx_lock(&mtxSharedAccessCompleted) != thrd_success)
	{
		mtx_unlock(&mtxExclusiveAccess);
		return false;
	}

	if(nExclusiveAccessCount == 0)
	{
		if(nCompletedSharedAccessCount > 0)
		{
			nSharedAccessCount -= nCompletedSharedAccessCount;
			nCompletedSharedAccessCount = 0;
		}
		if(nSharedAccessCount > 0)
		{
			nCompletedSharedAccessCount = -nSharedAccessCount;

			// pthread_cleanup_push (ptw32_rwlock_cancelwrwait, (void *) rwl);

			do
			{
				result = (cnd_wait(&cndSharedAccessCompleted, &mtxSharedAccessCompleted) == thrd_success);
			}
			while(result && (nCompletedSharedAccessCount < 0));

			// pthread_cleanup_pop ((result != 0) ? 1 : 0);

			if(result)
			{
				nSharedAccessCount = 0;
			}

		}
	}

	if(result)
	{
		nExclusiveAccessCount++;
	}
	return result;
}
Esempio n. 19
0
Tile* tile_wait_pull(SyncTileList* list){
	Tile* tile;
	TileNode* node;
	mtx_lock(&list->mtx);
	while(list->count==0){
		cnd_wait(&list->cnd,&list->mtx);
	}

	node = list->first;
	tile = node->tile;
	list->first = node->next;
	if (--list->count == 0) list->last=0;

	mtx_unlock(&list->mtx);
	free(node);
	return tile;
}
Esempio n. 20
0
static SquashStatus
squash_stream_send_to_thread (SquashStream* stream, SquashOperation operation) {
    SquashStreamPrivate* priv = stream->priv;
    SquashStatus result;

    priv->request = operation;
    cnd_signal (&(priv->request_cnd));
    mtx_unlock (&(priv->io_mtx));

    mtx_lock (&(priv->io_mtx));
    while ((result = priv->result) == SQUASH_STATUS_INVALID) {
        cnd_wait (&(priv->result_cnd), &(priv->io_mtx));
    }
    priv->result = SQUASH_STATUS_INVALID;

    if (priv->finished == true) {
        mtx_unlock (&(priv->io_mtx));
        thrd_join (priv->thread, NULL);
    }

    return result;
}
Esempio n. 21
0
/**
 * @brief Yield execution back to the main thread
 * @protected
 *
 * This function may only be called inside the processing thread
 * spawned for thread-based plugins.
 *
 * @param stream The stream
 * @param status Status code to return for the current request
 * @return The code of the next requested operation
 */
static SquashOperation
squash_stream_yield (SquashStream* stream, SquashStatus status) {
    SquashStreamPrivate* priv = stream->priv;
    SquashOperation operation;

    assert (stream != NULL);
    assert (priv != NULL);

    priv->request = SQUASH_OPERATION_INVALID;
    priv->result = status;

    cnd_signal (&(priv->result_cnd));
    mtx_unlock (&(priv->io_mtx));
    if (status < 0)
        thrd_exit (status);

    mtx_lock (&(priv->io_mtx));
    while ((operation = priv->request) == SQUASH_OPERATION_INVALID) {
        cnd_wait (&(priv->request_cnd), &(priv->io_mtx));
    }
    return operation;
}
Esempio n. 22
0
int cnd_timedwait_ms(cnd_t *cnd, mtx_t *mtx, int timeout_ms) {
        if (timeout_ms == -1 /* INFINITE*/)
                return cnd_wait(cnd, mtx);
#if defined(_TTHREAD_WIN32_)
        return _cnd_timedwait_win32(cnd, mtx, (DWORD)timeout_ms);
#else
        struct timeval tv;
        struct timespec ts;

        gettimeofday(&tv, NULL);
        ts.tv_sec = tv.tv_sec;
        ts.tv_nsec = tv.tv_usec * 1000;

        ts.tv_sec  += timeout_ms / 1000;
        ts.tv_nsec += (timeout_ms % 1000) * 1000000;

        if (ts.tv_nsec >= 1000000000) {
                ts.tv_sec++;
                ts.tv_nsec -= 1000000000;
        }

        return cnd_timedwait(cnd, mtx, &ts);
#endif
}
Esempio n. 23
0
void util_ringbuffer_enqueue( struct util_ringbuffer *ring,
                              const struct util_packet *packet )
{
   unsigned i;

   /* XXX: over-reliance on mutexes, etc:
    */
   mtx_lock(&ring->mutex);

   /* make sure we don't request an impossible amount of space
    */
   assert(packet->dwords <= ring->mask);

   /* Wait for free space:
    */
   while (util_ringbuffer_space(ring) < packet->dwords)
      cnd_wait(&ring->change, &ring->mutex);

   /* Copy data to ring:
    */
   for (i = 0; i < packet->dwords; i++) {

      /* Copy all dwords of the packet.  Note we're abusing the
       * typesystem a little - we're being passed a pointer to
       * something, but probably not an array of packet structs:
       */
      ring->buf[ring->head] = packet[i];
      ring->head++;
      ring->head &= ring->mask;
   }

   /* Signal change:
    */
   cnd_signal(&ring->change);
   mtx_unlock(&ring->mutex);
}
Esempio n. 24
0
/**
 * @brief Test that Metadata requests are retried properly when
 *        timing out due to high broker rtt.
 */
static void do_test_low_socket_timeout (const char *topic) {
        rd_kafka_t *rk;
        rd_kafka_conf_t *conf;
        rd_kafka_topic_t *rkt;
        rd_kafka_resp_err_t err;
        const struct rd_kafka_metadata *md;
        int res;

        mtx_init(&ctrl.lock, mtx_plain);
        cnd_init(&ctrl.cnd);

        TEST_SAY("Test Metadata request retries on timeout\n");

        test_conf_init(&conf, NULL, 60);
        test_conf_set(conf, "socket.timeout.ms", "1000");
        test_conf_set(conf, "socket.max.fails", "12345");
        test_conf_set(conf, "retry.backoff.ms", "5000");
        /* Avoid api version requests (with their own timeout) to get in
         * the way of our test */
        test_conf_set(conf, "api.version.request", "false");
        test_socket_enable(conf);
        test_curr->connect_cb = connect_cb;
        test_curr->is_fatal_cb = is_fatal_cb;

        rk = test_create_handle(RD_KAFKA_PRODUCER, conf);
        rkt = test_create_producer_topic(rk, topic, NULL);

        TEST_SAY("Waiting for sockem connect..\n");
        mtx_lock(&ctrl.lock);
        while (!ctrl.skm)
                cnd_wait(&ctrl.cnd, &ctrl.lock);
        mtx_unlock(&ctrl.lock);

        TEST_SAY("Connected, fire off a undelayed metadata() to "
                 "make sure connection is up\n");

        err = rd_kafka_metadata(rk, 0, rkt, &md, tmout_multip(2000));
        TEST_ASSERT(!err, "metadata(undelayed) failed: %s",
                    rd_kafka_err2str(err));
        rd_kafka_metadata_destroy(md);

        if (thrd_create(&ctrl.thrd, ctrl_thrd_main, NULL) != thrd_success)
                TEST_FAIL("Failed to create sockem ctrl thread");

        set_delay(0, 3000); /* Takes effect immediately */

        /* After two retries, remove the delay, the third retry
         * should kick in and work. */
        set_delay(((1000 /*socket.timeout.ms*/ +
                    5000 /*retry.backoff.ms*/) * 2) - 2000, 0);

        TEST_SAY("Calling metadata() again which should succeed after "
                 "3 internal retries\n");
        /* Metadata should be returned after the third retry */
        err = rd_kafka_metadata(rk, 0, rkt, &md,
                                ((1000 /*socket.timeout.ms*/ +
                                  5000 /*retry.backoff.ms*/) * 2) + 5000);
        TEST_SAY("metadata() returned %s\n", rd_kafka_err2str(err));
        TEST_ASSERT(!err, "metadata(undelayed) failed: %s",
                    rd_kafka_err2str(err));
        rd_kafka_metadata_destroy(md);

        rd_kafka_topic_destroy(rkt);
        rd_kafka_destroy(rk);

        /* Join controller thread */
        mtx_lock(&ctrl.lock);
        ctrl.term = 1;
        mtx_unlock(&ctrl.lock);
        thrd_join(ctrl.thrd, &res);

        cnd_destroy(&ctrl.cnd);
        mtx_destroy(&ctrl.lock);
}
Esempio n. 25
0
int TPTCPChild(void* Ptr){

	static char* SuccessResponse =
		" 200 OK\n"
		"Content-type: text/html\n"
		"Connection: close\n"
		"\n";
	static char *NotFoundResponse =
		" 404 Not Found\n"
		"Content-type: text/html\n"
		"Connection: close\n"
		"\n";
	static char* BadMethodResponse =
		" 501 Method Not Implemented\n"
		"Content-type: text/html\n"
		"Connection: close\n"
		"\n";
	
	int Recv = 0;
	int Send = 0;
	int SentLength = 0;
	int ReadLength = 0;
	int FileLength = 0;
	int PktSize = 1024;

	char *Method;
	char *URI;
	char *Version;
	char *ReceiveBuf;
	char *HeaderBuf;
	char ContentBuf[1025];
	char * FileBuffer = 0;
	
	Method = (char *)malloc(sizeof(char)* 20);
	URI = (char *)malloc(sizeof(char)* 256);
	Version = (char *)malloc(sizeof(char)* PktSize);
	HeaderBuf = (char *)malloc(sizeof(char)* PktSize);
	ReceiveBuf = (char *)malloc(sizeof(char)* PktSize);
	
	FILE * f;
	SOCKET TCPSock;
	
	while (1){
		mtx_lock(&ThMutex);
		if (SocketQueue.size == 0){
			cnd_wait(&cond, &ThMutex);
		}
		TCPSock = SocketQueue.Dequeue(&SocketQueue);
		mtx_unlock(&ThMutex);

		while (1){
			if ((Recv = recv(TCPSock, ReceiveBuf, PktSize, 0)) == SOCKET_ERROR){
				printf("recv() failed with error code: %d\n", WSAGetLastError());
				return 0;
			}
			else{
				sscanf(ReceiveBuf, "%s %s %s", Method, URI, Version);
				if (strcmp(Method, "GET") == 0){
					
					if (strcmp(URI, "/") == 0 || strcmp(URI, "/index.html") == 0){
						f = fopen("index.html", "r");
						strcat(Version, SuccessResponse);
					}
					else if (strcmp(URI, "/readme.html") == 0){
						f = fopen("readme.html", "r");
						strcat(Version, SuccessResponse);
					}
					else{
						f = fopen("404error.html", "r");
						strcat(Version, NotFoundResponse);
					}
				}
				else{
					f = fopen("404error.html", "r");
					strcat(Version, BadMethodResponse);
				}
				fseek(f, 0, SEEK_END);
				FileLength = ftell(f);
				fseek(f, 0, SEEK_SET);
				
				HeaderBuf = Version; //Store the header file
				while (1){
					if ((Send = send(TCPSock, HeaderBuf, strlen(HeaderBuf), 0)) == SOCKET_ERROR){
						printf("\nConnection failed with error code: %d\n", WSAGetLastError());
						break;
					}
					else{
						/*debug info*/
						//printf("send0 is finished\n");
						break;
					}
				}
				while (SentLength < FileLength){
					ReadLength = fread(ContentBuf, sizeof(char), 1024, f);
					ReadLength = send(TCPSock, ContentBuf, ReadLength, 0);
					SentLength = SentLength + ReadLength;
				}
				fclose(f);
				SentLength = 0;
				//Sleep(500);
				closesocket(TCPSock);
				break;
			}
		}
	}
}