blender/extern/verse/dist/v_network_in_que.c
2006-10-02 13:29:17 +00:00

141 lines
2.8 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "verse_header.h"
#include "v_cmd_buf.h"
#include "v_cmd_gen.h"
#include "v_connection.h"
#include "v_internal_verse.h"
#include "v_network.h"
#include "v_pack.h"
#if !defined(V_GENERATE_FUNC_MODE)
#include "v_network_in_que.h"
static VNetInPacked *v_niq_temp = NULL;
void v_niq_clear(VNetInQueue *queue)
{
queue->oldest = NULL;
queue->newest = NULL;
queue->packet_id = 2;
v_niq_timer_update(queue);
}
/* Set queue's last-used timestamp to "now". */
void v_niq_timer_update(VNetInQueue *queue)
{
v_n_get_current_time(&queue->seconds, &queue->fractions);
queue->acc_seconds = queue->acc_fractions = 0;
}
uint32 v_niq_time_out(VNetInQueue *queue)
{
uint32 fractions, f;
/* Magic code to disregard if the clock moves forward more than one second at a time.
* This should help keep Verse alive on e.g. a notebook that is suspended.
*/
v_n_get_current_time(NULL, &fractions);
if(fractions < queue->fractions)
f = 0xffffffffu - queue->fractions + fractions;
else
f = fractions - queue->fractions;
/* printf("now=%u last=%u -> f=%u\n", fractions, queue->fractions, f);*/
if(queue->acc_fractions + f < queue->acc_fractions)
queue->acc_seconds += 1;
queue->acc_fractions += f;
queue->fractions = fractions;
/* printf("queue at %p has seconds=%u, now=%u -> diff=%u\n", queue, queue->seconds, seconds, seconds - queue->seconds);*/
return queue->acc_seconds;
}
VNetInPacked * v_niq_get(VNetInQueue *queue, size_t *length)
{
VNetInPacked *p;
if(queue->oldest == NULL)
{
*length = 0;
return NULL;
}
/* pop oldest package */
p = queue->oldest;
queue->oldest = p->newer;
if(queue->oldest == NULL)
queue->newest = NULL;
else
((VNetInPacked *)queue->oldest)->older = NULL;
*length = p->size;
return p;
}
unsigned int v_niq_free(VNetInQueue *queue)
{
unsigned int i;
size_t length;
for(i = 0; v_niq_get(queue, &length) != NULL; i++)
;
return i;
}
void v_niq_release(VNetInQueue *queue, VNetInPacked *p)
{
/* push on v_niq_temp for re-use */
p->older = v_niq_temp;
v_niq_temp = p;
}
char *v_niq_store(VNetInQueue *queue, size_t length, unsigned int packet_id)
{
VNetInPacked *p;
v_niq_timer_update(queue);
if(packet_id < queue->packet_id)
return NULL;
while(queue->packet_id != packet_id)
{
verse_send_packet_nak(queue->packet_id++);
if(queue->packet_id == 0)
queue->packet_id++;
}
queue->packet_id++;
if(queue->packet_id == 0)
queue->packet_id++;
verse_send_packet_ack(packet_id);
if(v_niq_temp == NULL)
p = malloc(sizeof *p);
else
{
/* pop off v_niq_temp */
p = v_niq_temp;
v_niq_temp = p->older;
}
/* push as newest */
p->older = queue->newest;
p->newer = NULL;
if(queue->newest == NULL)
queue->oldest = p;
else
((VNetInPacked *)queue->newest)->newer = p;
queue->newest = p;
p->size = length;
return p->data;
}
#endif