Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
BIRD Internet Routing Daemon
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
3
Merge Requests
3
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
labs
BIRD Internet Routing Daemon
Commits
525fa2c1
Commit
525fa2c1
authored
Jun 05, 2000
by
Martin Mareš
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Documented sockets, events and timers.
parent
10304bed
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
196 additions
and
14 deletions
+196
-14
lib/Doc
lib/Doc
+1
-1
lib/event.c
lib/event.c
+54
-0
lib/resource.sgml
lib/resource.sgml
+1
-9
nest/Doc
nest/Doc
+1
-0
sysdep/unix/io.c
sysdep/unix/io.c
+139
-4
No files found.
lib/Doc
View file @
525fa2c1
...
...
@@ -6,5 +6,5 @@ D resource.sgml
S resource.c
S mempool.c
S slab.c
S socket.h
S event.c
S ../sysdep/unix/io.c
lib/event.c
View file @
525fa2c1
...
...
@@ -6,6 +6,21 @@
* Can be freely distributed and used under the terms of the GNU GPL.
*/
/**
* DOC: Events
*
* Events are there to keep track of deferred execution.
* Since BIRD is single-threaded, it requires long lasting tasks to be split to smaller
* parts, so that no module can monopolize the CPU. To split such a task, just create
* an &event resource, point it to the function you want to have called and call ev_schedule()
* to ask the core to run the event when nothing more important will require attention.
*
* You can also define your own event lists (the &event_list structure), enqueue your
* events in them and explicitly ask to run them.
*
* The actual implementation is system dependent.
*/
#include "nest/bird.h"
#include "lib/event.h"
...
...
@@ -39,6 +54,13 @@ static struct resclass ev_class = {
ev_dump
};
/**
* ev_new - create a new event
* @p: resource pool
*
* This function creates a new event resource. To use it,
* you need to fill the structure fields and call ev_schedule().
*/
event
*
ev_new
(
pool
*
p
)
{
...
...
@@ -50,6 +72,16 @@ ev_new(pool *p)
return
e
;
}
/**
* ev_run - run an event
* @e: an event
*
* This function explicitly runs the event @e (calls its hook
* function) and removes it from an event list if it's linked to any.
*
* From the hook function, you can call ev_enqueue() or ev_schedule()
* to re-add the event.
*/
inline
void
ev_run
(
event
*
e
)
{
...
...
@@ -57,6 +89,14 @@ ev_run(event *e)
e
->
hook
(
e
->
data
);
}
/**
* ev_enqueue - enqueue an event
* @l: an event list
* @e: an event
*
* ev_enqueue() stores the event @e to the specified event
* list @l which can be run by calling ev_run_list().
*/
inline
void
ev_enqueue
(
event_list
*
l
,
event
*
e
)
{
...
...
@@ -64,12 +104,26 @@ ev_enqueue(event_list *l, event *e)
add_tail
(
l
,
&
e
->
n
);
}
/**
* ev_schedule - schedule an event
* @e: an event
*
* This function schedules an event by enqueueing it to a system-wide
* event list which is run by the platform dependent code whenever
* appropriate.
*/
void
ev_schedule
(
event
*
e
)
{
ev_enqueue
(
&
global_event_list
,
e
);
}
/**
* ev_run_list - run an event list
* @l: an event list
*
* This function calls ev_run() for all events enqueued in the list @l.
*/
int
ev_run_list
(
event_list
*
l
)
{
...
...
lib/resource.sgml
View file @
525fa2c1
...
...
@@ -36,15 +36,7 @@ type.
<item><it/Memory blocks/
<item><it/Linear memory pools/ (<struct/linpool/)
<item><it/Slabs/ (<struct/slab/)
<item><it/Sockets/ (<struct/socket/)
<item><it/Events/ (<struct/event/)
<!--
are there to keep track of deferred execution.
Since BIRD is single-threaded, it requires long lasting tasks to be split to smaller
parts, so that no module can monopolize the CPU. To split such a task, just create
an <struct/event/ resource, point it to the function you want to have called and call <func/ev_schedule()/
to ask the core to run the event when nothing more important will require attention.
The actual implementation is system dependent.
-->
<item><it/Timers/ (<struct/timer/)
<item><it/Sockets/ (<struct/socket/)
</itemize>
nest/Doc
View file @
525fa2c1
...
...
@@ -9,3 +9,4 @@ S iface.c
S neighbor.c
S cli.c
S locks.c
# rt-dev.c documented in Protocols chapter
sysdep/unix/io.c
View file @
525fa2c1
...
...
@@ -73,8 +73,23 @@ tracked_fopen(pool *p, char *name, char *mode)
return
f
;
}
/*
* Timers
/**
* DOC: Timers
*
* Timers are resources which represent a wish of a module to call
* a function at the specified time. The platform dependent code
* doesn't guarantee the exact timing, only that a timer function
* won't be called before the requested time.
*
* In BIRD, real time is represented by values of the &bird_clock_t type
* which are integral numbers corresponding to a number of seconds since
* a fixed (but platform dependent) epoch. The current time can be read
* from a variable @now with reasonable accuracy.
*
* Each timer is described by a &timer structure containing a pointer
* to the handler function (@hook), data private to this function (@data),
* time the function should be called at (@expires, 0 for inactive timers),
* for the other fields see |timer.h|.
*/
#define NEAR_TIMER_LIMIT 4
...
...
@@ -115,6 +130,14 @@ static struct resclass tm_class = {
tm_dump
};
/**
* tm_new - create a timer
* @p: pool
*
* This function creates a new timer resource and returns
* a pointer to it. To use the timer, you need to fill in
* the structure fields and call tm_start() to start timing.
*/
timer
*
tm_new
(
pool
*
p
)
{
...
...
@@ -136,6 +159,23 @@ tm_insert_near(timer *t)
insert_node
(
&
t
->
n
,
n
->
prev
);
}
/**
* tm_start - start a timer
* @t: timer
* @after: number of seconds the timer should be run after
*
* This function schedules the hook function of the timer to
* be called after @after seconds. If the timer has been already
* started, it's @expire time is replaced by the new value.
*
* You can have set the @randomize field of @t, the timeout
* will be increased by a random number of seconds chosen
* uniformly from range 0 .. @randomize.
*
* You can call tm_start() from the handler function of the timer
* to request another run of the timer. Also, you can set the @recurrent
* field to have the timer re-added automatically with the same timeout.
*/
void
tm_start
(
timer
*
t
,
unsigned
after
)
{
...
...
@@ -159,6 +199,13 @@ tm_start(timer *t, unsigned after)
}
}
/**
* tm_stop - stop a timer
* @t: timer
*
* This function stops a timer. If the timer is already stopped,
* nothing happens.
*/
void
tm_stop
(
timer
*
t
)
{
...
...
@@ -250,6 +297,13 @@ tm_shot(void)
}
}
/**
* tm_parse_date - parse a date
* @x: date string
*
* tm_parse_date() takes a textual representation of a date (dd-mm-yyyy)
* and converts it to the corresponding value of type &bird_clock_t.
*/
bird_clock_t
tm_parse_date
(
char
*
x
)
{
...
...
@@ -268,6 +322,14 @@ tm_parse_date(char *x)
return
t
;
}
/**
* tm_format_date - convert date to textual representation
* @x: destination buffer of size %TM_DATE_BUFFER_SIZE
* @t: time
*
* This function formats the given time value @t to a textual
* date representation (dd-mm-yyyy).
*/
void
tm_format_date
(
char
*
x
,
bird_clock_t
t
)
{
...
...
@@ -277,6 +339,14 @@ tm_format_date(char *x, bird_clock_t t)
bsprintf
(
x
,
"%02d-%02d-%04d"
,
tm
->
tm_mday
,
tm
->
tm_mon
+
1
,
tm
->
tm_year
+
1900
);
}
/**
* tm_format_datetime - convert date and time to textual representation
* @x: destination buffer of size %TM_DATETIME_BUFFER_SIZE
* @t: time
*
* This function formats the given time value @t to a textual
* date/time representation (dd-mm-yyyy hh:mm:ss).
*/
void
tm_format_datetime
(
char
*
x
,
bird_clock_t
t
)
{
...
...
@@ -287,6 +357,14 @@ tm_format_datetime(char *x, bird_clock_t t)
strcpy
(
x
,
"<too-long>"
);
}
/**
* tm_format_reltime - convert date and time to relative textual representation
* @x: destination buffer of size %TM_RELTIME_BUFFER_SIZE
* @t: time
*
* This function formats the given time value @t to a short
* textual representation relative to the current time.
*/
void
tm_format_reltime
(
char
*
x
,
bird_clock_t
t
)
{
...
...
@@ -303,8 +381,17 @@ tm_format_reltime(char *x, bird_clock_t t)
bsprintf
(
x
,
"%d"
,
tm
->
tm_year
+
1900
);
}
/*
* Sockets
/**
* DOC: Sockets
*
* Socket resources represent network connections. Their data structure (&socket)
* contains a lot of fields defining the exact type of the socket, the local and
* remote addresses and ports, pointers to socket buffers and finally pointers to
* hook functions to be called when new data have arrived to the receive buffer
* (@rx_hook), when the contents of the transmit buffer have been transmitted
* (@tx_hook) and when an error or connection close occurs (@err_hook).
*
* You should not use rfree() from inside a socket hook, please use sk_close() instead.
*/
#ifndef SOL_IP
...
...
@@ -350,6 +437,14 @@ static struct resclass sk_class = {
sk_dump
};
/**
* sk_new - create a socket
* @p: pool
*
* This function creates a new socket resource. If you want to use it,
* you need to fill in all the required fields of the structure and
* call sk_open() to do the actual opening of the socket.
*/
sock
*
sk_new
(
pool
*
p
)
{
...
...
@@ -502,6 +597,16 @@ sk_passive_connected(sock *s, struct sockaddr *sa, int al, int type)
return
0
;
}
/**
* sk_open - open a socket
* @s: socket
*
* This function takes a socket resource created by sk_new() and
* initialized by the user and binds a corresponding network connection
* to it.
*
* Result: 0 for success, -1 for an error.
*/
int
sk_open
(
sock
*
s
)
{
...
...
@@ -683,6 +788,14 @@ bad:
return
-
1
;
}
/**
* sk_close - close a socket
* @s: a socket
*
* If sk_close() has been called from outside of any socket hook,
* it translates to a rfree(), else it just marks the socket for
* deletion as soon as the socket hook returns.
*/
void
sk_close
(
sock
*
s
)
{
...
...
@@ -746,6 +859,18 @@ sk_maybe_write(sock *s)
}
}
/**
* sk_send - send data to a socket
* @s: socket
* @len: number of bytes to send
*
* This function sends @len bytes of data prepared in the
* transmit buffer of the socket @s to the network connection.
* If the packet can be sent immediately, it does so and returns
* 1, else it queues the packet for later processing, returns 0
* and calls the @tx_hook of the socket when the tranmission
* takes place.
*/
int
sk_send
(
sock
*
s
,
unsigned
len
)
{
...
...
@@ -756,6 +881,16 @@ sk_send(sock *s, unsigned len)
return
sk_maybe_write
(
s
);
}
/**
* sk_send_to - send data to a specific destination
* @s: socket
* @len: number of bytes to send
* @addr: IP address to send the packet to
* @port: port to send the packet to
*
* This is a sk_send() replacement for connectionless packet sockets
* which allows destination of the packet to be chosen dynamically.
*/
int
sk_send_to
(
sock
*
s
,
unsigned
len
,
ip_addr
addr
,
unsigned
port
)
{
...
...
Write
Preview
Markdown
is supported
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