Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
LARN
PRRT
Commits
7c14c771
Commit
7c14c771
authored
Nov 30, 2015
by
Andreas Schmidt
Browse files
Using lists to send outgoing packets in a separate thread.
parent
b5840714
Changes
8
Hide whitespace changes
Inline
Side-by-side
CMakeLists.txt
View file @
7c14c771
...
...
@@ -9,7 +9,7 @@ find_package (Threads)
add_subdirectory
(
prrt
)
add_library
(
PRRT prrt/socket.c prrt/block.c prrt/block.h prrt/packet.c prrt/packet.h prrt/feedback_receiver.c prrt/feedback_receiver.h prrt/data_transmitter.c prrt/data_transmitter.h
)
add_library
(
UTIL util/common.c util/common.h
)
add_library
(
UTIL util/common.c util/common.h
util/list.c util/list.h
)
add_executable
(
sender sender.c
)
add_executable
(
receiver receiver.c
)
...
...
prrt/data_transmitter.c
View file @
7c14c771
#include
<unistd.h>
#include
<netinet/in.h>
#include
<string.h>
#include
<netdb.h>
#include
"data_transmitter.h"
#include
"socket.h"
void
*
send_data_loop
(
void
*
ptr
)
{
prrt_socket
*
sock_ptr
=
ptr
;
while
(
1
)
{
pthread_mutex_lock
(
&
sock_ptr
->
is_data_available
);
while
(
sock_ptr
->
packets_count
==
0
)
{
pthread_cond_wait
(
&
sock_ptr
->
is_data_availab
le_cv
,
&
sock_ptr
->
is_data_available
);
pthread_mutex_lock
(
&
sock_ptr
->
out_queue_filled_mutex
);
while
(
List_count
(
sock_ptr
->
out_queue
)
==
0
)
{
pthread_cond_wait
(
&
sock_ptr
->
out_queue_fil
le
d
_cv
,
&
sock_ptr
->
out_queue_filled_mutex
);
}
// TODO: take a packet from the list and send it
sock_ptr
->
packets_count
--
;
printf
(
"TAKING OUT (NOW: %d)
\n
"
,
sock_ptr
->
packets_count
);
prrt_packet
*
packet
=
List_shift
(
sock_ptr
->
out_queue
);
uint8_t
buf
[
MAX_PAYLOAD_LENGTH
];
uint32_t
length
=
packet_size
(
packet
);
if
(
encode_packet
(
buf
,
MAX_PAYLOAD_LENGTH
,
packet
)
<
0
)
{
perror
(
"BUF too small."
);
exit
(
0
);
}
// SENDING TO ALL RECEIVERS
int
i
;
for
(
i
=
0
;
i
<
sock_ptr
->
receiver_len
;
i
++
)
{
prrt_receiver
recv
=
sock_ptr
->
receivers
[
i
];
struct
hostent
*
hp
;
struct
sockaddr_in
targetaddr
;
memset
((
char
*
)
&
targetaddr
,
0
,
sizeof
(
targetaddr
));
targetaddr
.
sin_family
=
AF_INET
;
targetaddr
.
sin_port
=
htons
(
recv
.
port
);
hp
=
gethostbyname
(
recv
.
host_name
);
memcpy
((
void
*
)
&
targetaddr
.
sin_addr
,
hp
->
h_addr_list
[
0
],
(
size_t
)
hp
->
h_length
);
if
((
sendto
(
sock_ptr
->
fd_data
,
buf
,
length
,
0
,
(
struct
sockaddr
*
)
&
targetaddr
,
sizeof
(
targetaddr
))
<
0
))
{
perror
(
"sendto failed"
);
exit
(
1
);
break
;
}
}
delete_packet
(
packet
);
pthread_mutex_unlock
(
&
sock_ptr
->
is_data_available
);
usleep
(
1
000
);
pthread_mutex_unlock
(
&
sock_ptr
->
out_queue_filled_mutex
);
usleep
(
1
);
}
}
prrt/socket.c
View file @
7c14c771
...
...
@@ -47,8 +47,10 @@ int prrt_create_socket(prrt_socket *sock_ptr, uint16_t port, uint8_t is_sender)
}
if
(
is_sender
)
{
pthread_mutex_init
(
&
sock_ptr
->
is_data_available
,
NULL
);
pthread_cond_init
(
&
sock_ptr
->
is_data_available_cv
,
NULL
);
pthread_mutex_init
(
&
sock_ptr
->
out_queue_filled_mutex
,
NULL
);
pthread_cond_init
(
&
sock_ptr
->
out_queue_filled_cv
,
NULL
);
sock_ptr
->
out_queue
=
List_create
();
int
rc
=
pthread_create
(
&
sock_ptr
->
receive_thread
,
NULL
,
receive_feedback_loop
,
(
void
*
)
sock_ptr
);
if
(
rc
)
{
...
...
@@ -69,7 +71,7 @@ int prrt_create_socket(prrt_socket *sock_ptr, uint16_t port, uint8_t is_sender)
}
int
prrt_connect
(
prrt_socket
*
sock_ptr
,
char
*
host
,
uint16_t
port
)
{
prrt_receiver
recv
=
{
host
,
port
};
prrt_receiver
recv
=
{
host
,
port
};
if
(
sock_ptr
->
receiver_len
<
PRRT_MAX_RECEIVER_COUNT
)
{
sock_ptr
->
receivers
[
sock_ptr
->
receiver_len
]
=
recv
;
...
...
@@ -82,51 +84,16 @@ int prrt_connect(prrt_socket *sock_ptr, char *host, uint16_t port) {
}
int
prrt_send
(
prrt_socket
*
sock_ptr
,
const
void
*
data
,
size_t
data_len
)
{
pthread_mutex_lock
(
&
sock_ptr
->
out_queue_filled_mutex
);
pthread_mutex_lock
(
&
sock_ptr
->
is_data_available
);
sock_ptr
->
packets_count
++
;
printf
(
"ADDING (NOW: %d)
\n
"
,
sock_ptr
->
packets_count
);
pthread_cond_signal
(
&
sock_ptr
->
is_data_available_cv
);
// TODO: add a packet to the list
pthread_mutex_unlock
(
&
sock_ptr
->
is_data_available
);
int
res
=
0
;
prrt_packet
*
packet
=
malloc
(
sizeof
(
prrt_packet
));
create_packet_data
(
packet
,
5
,
data
,
data_len
);
uint8_t
buf
[
MAX_PAYLOAD_LENGTH
];
uint32_t
length
=
packet_size
(
packet
);
if
(
encode_packet
(
buf
,
MAX_PAYLOAD_LENGTH
,
packet
)
<
0
)
{
perror
(
"BUF too small."
);
return
-
1
;
}
List_push
(
sock_ptr
->
out_queue
,
packet
);
pthread_cond_signal
(
&
sock_ptr
->
out_queue_filled_cv
);
pthread_mutex_unlock
(
&
sock_ptr
->
out_queue_filled_mutex
);
// SENDING TO ALL RECEIVERS
int
i
;
for
(
i
=
0
;
i
<
sock_ptr
->
receiver_len
;
i
++
)
{
prrt_receiver
recv
=
sock_ptr
->
receivers
[
i
];
struct
hostent
*
hp
;
struct
sockaddr_in
targetaddr
;
memset
((
char
*
)
&
targetaddr
,
0
,
sizeof
(
targetaddr
));
targetaddr
.
sin_family
=
AF_INET
;
targetaddr
.
sin_port
=
htons
(
recv
.
port
);
hp
=
gethostbyname
(
recv
.
host_name
);
memcpy
((
void
*
)
&
targetaddr
.
sin_addr
,
hp
->
h_addr_list
[
0
],
(
size_t
)
hp
->
h_length
);
if
((
sendto
(
sock_ptr
->
fd_data
,
buf
,
length
,
0
,
(
struct
sockaddr
*
)
&
targetaddr
,
sizeof
(
targetaddr
))
<
0
))
{
perror
(
"sendto failed"
);
res
=
-
1
;
break
;
}
}
delete_packet
(
packet
);
return
res
;
return
0
;
}
prrt_packet
*
prrt_recv
(
prrt_socket
*
sock_ptr
)
{
...
...
@@ -175,8 +142,9 @@ int prrt_close_socket(prrt_socket *sock_ptr) {
// TODO: clean up all receivers
pthread_mutex_destroy
(
&
sock_ptr
->
is_data_available
);
pthread_cond_destroy
(
&
sock_ptr
->
is_data_available_cv
);
pthread_mutex_destroy
(
&
sock_ptr
->
out_queue_filled_mutex
);
pthread_cond_destroy
(
&
sock_ptr
->
out_queue_filled_cv
);
List_destroy
(
sock_ptr
->
out_queue
);
close
(
sock_ptr
->
fd_data
);
close
(
sock_ptr
->
fd_feedback
);
...
...
prrt/socket.h
View file @
7c14c771
...
...
@@ -6,6 +6,7 @@
#include
<stdio.h>
#include
"../defines.h"
#include
"packet.h"
#include
"../util/list.h"
#include
<pthread.h>
typedef
struct
{
...
...
@@ -17,9 +18,12 @@ typedef struct {
int
fd_data
;
int
fd_feedback
;
pthread_t
receive_thread
;
pthread_mutex_t
is_data_available
;
pthread_cond_t
is_data_available_cv
;
pthread_t
send_thread
;
pthread_mutex_t
out_queue_filled_mutex
;
pthread_cond_t
out_queue_filled_cv
;
List
*
out_queue
;
prrt_receiver
receivers
[
PRRT_MAX_RECEIVER_COUNT
];
int
receiver_len
;
uint16_t
packets_count
;
...
...
receiver.c
View file @
7c14c771
...
...
@@ -33,7 +33,7 @@ int main(int argc, char* const argv[]) {
buffer
[
pkt
->
payload_len
-
PRRT_PACKET_DATA_HEADER_SIZE
]
=
'\0'
;
printf
(
"%s
\n
"
,
buffer
);
}
usleep
(
1
000
*
1000
);
usleep
(
1
);
}
prrt_close_socket
(
&
sock
);
...
...
sender.c
View file @
7c14c771
...
...
@@ -30,8 +30,9 @@ int main(int argc, char* const argv) {
printf
(
"SENDING
\n
"
);
for
(
i
=
0
;
i
<
5
;
i
++
)
{
char
*
message
=
"this is a message"
;
prrt_send
(
&
sock
,
message
,
strlen
(
message
));
char
buf
[
30
];
sprintf
(
buf
,
"this is a message %d"
,
i
);
prrt_send
(
&
sock
,
buf
,
strlen
(
buf
));
}
usleep
(
5000
*
1000
);
...
...
util/list.c
0 → 100644
View file @
7c14c771
#include
"list.h"
// Taken from: http://c.learncodethehardway.org/book/ex32.html
List
*
List_create
()
{
return
calloc
(
1
,
sizeof
(
List
));
}
void
List_destroy
(
List
*
list
)
{
LIST_FOREACH
(
list
,
first
,
next
,
cur
)
{
if
(
cur
->
prev
)
{
free
(
cur
->
prev
);
}
}
free
(
list
->
last
);
free
(
list
);
}
void
List_clear
(
List
*
list
)
{
LIST_FOREACH
(
list
,
first
,
next
,
cur
)
{
free
(
cur
->
value
);
}
}
void
List_clear_destroy
(
List
*
list
)
{
List_clear
(
list
);
List_destroy
(
list
);
}
void
List_push
(
List
*
list
,
void
*
value
)
{
ListNode
*
node
=
calloc
(
1
,
sizeof
(
ListNode
));
node
->
value
=
value
;
if
(
list
->
last
==
NULL
)
{
list
->
first
=
node
;
list
->
last
=
node
;
}
else
{
list
->
last
->
next
=
node
;
node
->
prev
=
list
->
last
;
list
->
last
=
node
;
}
list
->
count
++
;
error:
return
;
}
void
*
List_pop
(
List
*
list
)
{
ListNode
*
node
=
list
->
last
;
return
node
!=
NULL
?
List_remove
(
list
,
node
)
:
NULL
;
}
void
List_unshift
(
List
*
list
,
void
*
value
)
{
ListNode
*
node
=
calloc
(
1
,
sizeof
(
ListNode
));
node
->
value
=
value
;
if
(
list
->
first
==
NULL
)
{
list
->
first
=
node
;
list
->
last
=
node
;
}
else
{
node
->
next
=
list
->
first
;
list
->
first
->
prev
=
node
;
list
->
first
=
node
;
}
list
->
count
++
;
error:
return
;
}
void
*
List_shift
(
List
*
list
)
{
ListNode
*
node
=
list
->
first
;
return
node
!=
NULL
?
List_remove
(
list
,
node
)
:
NULL
;
}
void
*
List_remove
(
List
*
list
,
ListNode
*
node
)
{
void
*
result
=
NULL
;
if
(
node
==
list
->
first
&&
node
==
list
->
last
)
{
list
->
first
=
NULL
;
list
->
last
=
NULL
;
}
else
if
(
node
==
list
->
first
)
{
list
->
first
=
node
->
next
;
list
->
first
->
prev
=
NULL
;
}
else
if
(
node
==
list
->
last
)
{
list
->
last
=
node
->
prev
;
list
->
last
->
next
=
NULL
;
}
else
{
ListNode
*
after
=
node
->
next
;
ListNode
*
before
=
node
->
prev
;
after
->
prev
=
before
;
before
->
next
=
after
;
}
list
->
count
--
;
result
=
node
->
value
;
free
(
node
);
error:
return
result
;
}
\ No newline at end of file
util/list.h
0 → 100644
View file @
7c14c771
#ifndef PRRT_LIST_H
#define PRRT_LIST_H
#include
<stdlib.h>
// Taken from: http://c.learncodethehardway.org/book/ex32.html
struct
ListNode
;
typedef
struct
ListNode
{
struct
ListNode
*
next
;
struct
ListNode
*
prev
;
void
*
value
;
}
ListNode
;
typedef
struct
List
{
int
count
;
ListNode
*
first
;
ListNode
*
last
;
}
List
;
List
*
List_create
();
void
List_destroy
(
List
*
list
);
void
List_clear
(
List
*
list
);
void
List_clear_destroy
(
List
*
list
);
#define List_count(A) ((A)->count)
#define List_first(A) ((A)->first != NULL ? (A)->first->value : NULL)
#define List_last(A) ((A)->last != NULL ? (A)->last->value : NULL)
void
List_push
(
List
*
list
,
void
*
value
);
void
*
List_pop
(
List
*
list
);
void
List_unshift
(
List
*
list
,
void
*
value
);
void
*
List_shift
(
List
*
list
);
void
*
List_remove
(
List
*
list
,
ListNode
*
node
);
#define LIST_FOREACH(L, S, M, V) ListNode *_node = NULL;\
ListNode *V = NULL;\
for(V = _node = L->S; _node != NULL; V = _node = _node->M)
#endif //PRRT_LIST_H
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment