mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-29 05:40:23 -04:00
latency
esound volume changing git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@43 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
d571be6f51
commit
961fb4466a
7 changed files with 167 additions and 23 deletions
|
|
@ -181,6 +181,7 @@ typedef int esd_client_state_t;
|
||||||
|
|
||||||
/* switch endian order for cross platform playing */
|
/* switch endian order for cross platform playing */
|
||||||
#define swap_endian_32(x) ((x >> 24) | ((x >> 8) & 0xFF00) | (((x & 0xFF00) << 8)) | (x << 24))
|
#define swap_endian_32(x) ((x >> 24) | ((x >> 8) & 0xFF00) | (((x & 0xFF00) << 8)) | (x << 24))
|
||||||
|
#define maybe_swap_endian_32(c,x) ((c) ? swap_endian_32(x) : x)
|
||||||
|
|
||||||
/* the endian key is transferred in binary, if it's read into int, */
|
/* the endian key is transferred in binary, if it's read into int, */
|
||||||
/* and matches ESD_ENDIAN_KEY (ENDN), then the endianness of the */
|
/* and matches ESD_ENDIAN_KEY (ENDN), then the endianness of the */
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ int main(int argc, char *argv[]) {
|
||||||
c = core_new(pa_mainloop_get_api(mainloop));
|
c = core_new(pa_mainloop_get_api(mainloop));
|
||||||
assert(c);
|
assert(c);
|
||||||
|
|
||||||
module_load(c, "module-oss", "/dev/dsp1");
|
module_load(c, "module-oss-mmap", "/dev/dsp1");
|
||||||
/* module_load(c, "module-pipe-sink", NULL);
|
/* module_load(c, "module-pipe-sink", NULL);
|
||||||
module_load(c, "module-simple-protocol-tcp", NULL);
|
module_load(c, "module-simple-protocol-tcp", NULL);
|
||||||
module_load(c, "module-simple-protocol-unix", NULL);
|
module_load(c, "module-simple-protocol-unix", NULL);
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
/* This is heavily based on esound's code */
|
/* This is heavily based on esound's code */
|
||||||
|
|
||||||
struct connection {
|
struct connection {
|
||||||
|
uint32_t index;
|
||||||
struct protocol_esound *protocol;
|
struct protocol_esound *protocol;
|
||||||
struct iochannel *io;
|
struct iochannel *io;
|
||||||
struct client *client;
|
struct client *client;
|
||||||
|
|
@ -36,6 +37,7 @@ struct protocol_esound {
|
||||||
struct socket_server *server;
|
struct socket_server *server;
|
||||||
struct idxset *connections;
|
struct idxset *connections;
|
||||||
uint32_t sink_index;
|
uint32_t sink_index;
|
||||||
|
unsigned n_player;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct proto_handler {
|
typedef struct proto_handler {
|
||||||
|
|
@ -47,7 +49,7 @@ typedef struct proto_handler {
|
||||||
#define MEMBLOCKQ_LENGTH (10*1204)
|
#define MEMBLOCKQ_LENGTH (10*1204)
|
||||||
#define MEMBLOCKQ_PREBUF (2*1024)
|
#define MEMBLOCKQ_PREBUF (2*1024)
|
||||||
|
|
||||||
#define BUFSIZE PIPE_BUF
|
#define BUFSIZE (1024)
|
||||||
|
|
||||||
static void sink_input_drop_cb(struct sink_input *i, size_t length);
|
static void sink_input_drop_cb(struct sink_input *i, size_t length);
|
||||||
static int sink_input_peek_cb(struct sink_input *i, struct memchunk *chunk);
|
static int sink_input_peek_cb(struct sink_input *i, struct memchunk *chunk);
|
||||||
|
|
@ -59,6 +61,8 @@ static int esd_proto_stream_play(struct connection *c, const void *data, size_t
|
||||||
static int esd_proto_stream_record(struct connection *c, const void *data, size_t length);
|
static int esd_proto_stream_record(struct connection *c, const void *data, size_t length);
|
||||||
static int esd_proto_get_latency(struct connection *c, const void *data, size_t length);
|
static int esd_proto_get_latency(struct connection *c, const void *data, size_t length);
|
||||||
static int esd_proto_server_info(struct connection *c, const void *data, size_t length);
|
static int esd_proto_server_info(struct connection *c, const void *data, size_t length);
|
||||||
|
static int esd_proto_all_info(struct connection *c, const void *data, size_t length);
|
||||||
|
static int esd_proto_stream_pan(struct connection *c, const void *data, size_t length);
|
||||||
|
|
||||||
static int do_write(struct connection *c);
|
static int do_write(struct connection *c);
|
||||||
|
|
||||||
|
|
@ -86,11 +90,11 @@ static struct proto_handler proto_map[ESD_PROTO_MAX] = {
|
||||||
{ ESD_NAME_MAX + 2 * sizeof(int), NULL, "stream filter" },
|
{ ESD_NAME_MAX + 2 * sizeof(int), NULL, "stream filter" },
|
||||||
|
|
||||||
{ sizeof(int), esd_proto_server_info, "server info" },
|
{ sizeof(int), esd_proto_server_info, "server info" },
|
||||||
{ sizeof(int), NULL, "all info" },
|
{ sizeof(int), esd_proto_all_info, "all info" },
|
||||||
{ -1, NULL, "TODO: subscribe" },
|
{ -1, NULL, "TODO: subscribe" },
|
||||||
{ -1, NULL, "TODO: unsubscribe" },
|
{ -1, NULL, "TODO: unsubscribe" },
|
||||||
|
|
||||||
{ 3 * sizeof(int), NULL, "stream pan"},
|
{ 3 * sizeof(int), esd_proto_stream_pan, "stream pan"},
|
||||||
{ 3 * sizeof(int), NULL, "sample pan" },
|
{ 3 * sizeof(int), NULL, "sample pan" },
|
||||||
|
|
||||||
{ sizeof(int), NULL, "standby mode" },
|
{ sizeof(int), NULL, "standby mode" },
|
||||||
|
|
@ -102,6 +106,9 @@ static void connection_free(struct connection *c) {
|
||||||
assert(c);
|
assert(c);
|
||||||
idxset_remove_by_data(c->protocol->connections, c, NULL);
|
idxset_remove_by_data(c->protocol->connections, c, NULL);
|
||||||
|
|
||||||
|
if (c->state == ESD_STREAMING_DATA)
|
||||||
|
c->protocol->n_player--;
|
||||||
|
|
||||||
client_free(c->client);
|
client_free(c->client);
|
||||||
|
|
||||||
if (c->sink_input)
|
if (c->sink_input)
|
||||||
|
|
@ -170,9 +177,6 @@ static int esd_proto_connect(struct connection *c, const void *data, size_t leng
|
||||||
ok = connection_write(c, sizeof(int));
|
ok = connection_write(c, sizeof(int));
|
||||||
assert(ok);
|
assert(ok);
|
||||||
*ok = 1;
|
*ok = 1;
|
||||||
|
|
||||||
do_write(c);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -183,13 +187,8 @@ static int esd_proto_stream_play(struct connection *c, const void *data, size_t
|
||||||
struct pa_sample_spec ss;
|
struct pa_sample_spec ss;
|
||||||
assert(length == (sizeof(int)*2+ESD_NAME_MAX));
|
assert(length == (sizeof(int)*2+ESD_NAME_MAX));
|
||||||
|
|
||||||
format = *(int*)data;
|
format = maybe_swap_endian_32(c->swap_byte_order, *(int*)data);
|
||||||
rate = *((int*)data + 1);
|
rate = maybe_swap_endian_32(c->swap_byte_order, *((int*)data + 1));
|
||||||
|
|
||||||
if (c->swap_byte_order)
|
|
||||||
format = swap_endian_32(format);
|
|
||||||
if (c->swap_byte_order)
|
|
||||||
rate = swap_endian_32(rate);
|
|
||||||
|
|
||||||
ss.rate = rate;
|
ss.rate = rate;
|
||||||
ss.channels = ((format & ESD_MASK_CHAN) == ESD_STEREO) ? 2 : 1;
|
ss.channels = ((format & ESD_MASK_CHAN) == ESD_STEREO) ? 2 : 1;
|
||||||
|
|
@ -222,6 +221,8 @@ static int esd_proto_stream_play(struct connection *c, const void *data, size_t
|
||||||
|
|
||||||
c->state = ESD_STREAMING_DATA;
|
c->state = ESD_STREAMING_DATA;
|
||||||
|
|
||||||
|
c->protocol->n_player++;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -234,21 +235,19 @@ static int esd_proto_stream_record(struct connection *c, const void *data, size_
|
||||||
static int esd_proto_get_latency(struct connection *c, const void *data, size_t length) {
|
static int esd_proto_get_latency(struct connection *c, const void *data, size_t length) {
|
||||||
struct sink *sink;
|
struct sink *sink;
|
||||||
int latency, *lag;
|
int latency, *lag;
|
||||||
assert(c && data && length == 0);
|
assert(c && !data && length == 0);
|
||||||
|
|
||||||
if (!(sink = get_output_sink(c->protocol)))
|
if (!(sink = get_output_sink(c->protocol)))
|
||||||
latency = 0;
|
latency = 0;
|
||||||
else {
|
else {
|
||||||
float usec = sink_get_latency(sink);
|
float usec = sink_get_latency(sink);
|
||||||
usec += pa_samples_usec(MEMBLOCKQ_LENGTH, &sink->sample_spec);
|
usec += pa_samples_usec(MEMBLOCKQ_LENGTH-BUFSIZE, &sink->sample_spec);
|
||||||
latency = (int) (usec*441/10000);
|
latency = (int) ((usec*44100)/1000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
lag = connection_write(c, sizeof(int));
|
lag = connection_write(c, sizeof(int));
|
||||||
assert(lag);
|
assert(lag);
|
||||||
*lag = c->swap_byte_order ? swap_endian_32(latency) : latency;
|
*lag = c->swap_byte_order ? swap_endian_32(latency) : latency;
|
||||||
|
|
||||||
do_write(c);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -267,9 +266,94 @@ static int esd_proto_server_info(struct connection *c, const void *data, size_t
|
||||||
response = connection_write(c, sizeof(int)*3);
|
response = connection_write(c, sizeof(int)*3);
|
||||||
assert(response);
|
assert(response);
|
||||||
*(response++) = 0;
|
*(response++) = 0;
|
||||||
*(response++) = c->swap_byte_order ? swap_endian_32(rate) : rate;
|
*(response++) = maybe_swap_endian_32(c->swap_byte_order, rate);
|
||||||
*(response++) = c->swap_byte_order ? swap_endian_32(format) : format;
|
*(response++) = maybe_swap_endian_32(c->swap_byte_order, format);
|
||||||
do_write(c);
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int esd_proto_all_info(struct connection *c, const void *data, size_t length) {
|
||||||
|
void *response;
|
||||||
|
size_t t, k, s;
|
||||||
|
struct connection *conn;
|
||||||
|
size_t index = IDXSET_INVALID;
|
||||||
|
assert(c && data && length == sizeof(int));
|
||||||
|
|
||||||
|
if (esd_proto_server_info(c, data, length) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
k = sizeof(int)*5+ESD_NAME_MAX;
|
||||||
|
s = sizeof(int)*6+ESD_NAME_MAX;
|
||||||
|
response = connection_write(c, (t = s+k*(c->protocol->n_player+1)));
|
||||||
|
assert(k);
|
||||||
|
|
||||||
|
for (conn = idxset_first(c->protocol->connections, &index); conn; conn = idxset_next(c->protocol->connections, &index)) {
|
||||||
|
int format = ESD_BITS16 | ESD_STEREO, rate = 44100, volume = 0xFF;
|
||||||
|
|
||||||
|
if (conn->state != ESD_STREAMING_DATA)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
assert(t >= s+k+k);
|
||||||
|
|
||||||
|
if (conn->sink_input) {
|
||||||
|
rate = conn->sink_input->sample_spec.rate;
|
||||||
|
volume = (conn->sink_input->volume*0xFF)/0x100;
|
||||||
|
format = (conn->sink_input->sample_spec.format == PA_SAMPLE_U8) ? ESD_BITS8 : ESD_BITS16;
|
||||||
|
format |= (conn->sink_input->sample_spec.channels >= 2) ? ESD_STEREO : ESD_MONO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* id */
|
||||||
|
*((int*) response) = maybe_swap_endian_32(c->swap_byte_order, (int) conn->index);
|
||||||
|
response += sizeof(int);
|
||||||
|
|
||||||
|
/* name */
|
||||||
|
assert(conn->client);
|
||||||
|
strncpy(response, conn->client->name, ESD_NAME_MAX);
|
||||||
|
response += ESD_NAME_MAX;
|
||||||
|
|
||||||
|
/* rate */
|
||||||
|
*((int*) response) = maybe_swap_endian_32(c->swap_byte_order, rate);
|
||||||
|
response += sizeof(int);
|
||||||
|
|
||||||
|
/* left */
|
||||||
|
*((int*) response) = maybe_swap_endian_32(c->swap_byte_order, volume);
|
||||||
|
response += sizeof(int);
|
||||||
|
|
||||||
|
/*right*/
|
||||||
|
*((int*) response) = maybe_swap_endian_32(c->swap_byte_order, volume);
|
||||||
|
response += sizeof(int);
|
||||||
|
|
||||||
|
/*format*/
|
||||||
|
*((int*) response) = maybe_swap_endian_32(c->swap_byte_order, format);
|
||||||
|
response += sizeof(int);
|
||||||
|
|
||||||
|
t-= k;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(t == s+k);
|
||||||
|
memset(response, 0, t);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int esd_proto_stream_pan(struct connection *c, const void *data, size_t length) {
|
||||||
|
int *ok;
|
||||||
|
uint32_t index, volume;
|
||||||
|
struct connection *conn;
|
||||||
|
assert(c && data && length == sizeof(int)*3);
|
||||||
|
|
||||||
|
index = (uint32_t) maybe_swap_endian_32(c->swap_byte_order, *(int*)data);
|
||||||
|
volume = (uint32_t) maybe_swap_endian_32(c->swap_byte_order, *((int*)data + 1));
|
||||||
|
volume = (volume*0x100)/0xFF;
|
||||||
|
|
||||||
|
ok = connection_write(c, sizeof(int));
|
||||||
|
assert(ok);
|
||||||
|
|
||||||
|
if ((conn = idxset_get_by_index(c->protocol->connections, index))) {
|
||||||
|
assert(conn->sink_input);
|
||||||
|
conn->sink_input->volume = volume;
|
||||||
|
*ok = 1;
|
||||||
|
} else
|
||||||
|
*ok = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -380,6 +464,7 @@ static int do_read(struct connection *c) {
|
||||||
memblock_unref(chunk.memblock);
|
memblock_unref(chunk.memblock);
|
||||||
assert(c->sink_input);
|
assert(c->sink_input);
|
||||||
sink_notify(c->sink_input->sink);
|
sink_notify(c->sink_input->sink);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
||||||
|
|
@ -487,7 +572,7 @@ static void on_connection(struct socket_server*s, struct iochannel *io, void *us
|
||||||
c->sink_input = NULL;
|
c->sink_input = NULL;
|
||||||
c->input_memblockq = NULL;
|
c->input_memblockq = NULL;
|
||||||
|
|
||||||
idxset_put(c->protocol->connections, c, NULL);
|
idxset_put(c->protocol->connections, c, &c->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** entry points ***/
|
/*** entry points ***/
|
||||||
|
|
@ -505,6 +590,8 @@ struct protocol_esound* protocol_esound_new(struct core*core, struct socket_serv
|
||||||
assert(p->connections);
|
assert(p->connections);
|
||||||
p->sink_index = IDXSET_INVALID;
|
p->sink_index = IDXSET_INVALID;
|
||||||
|
|
||||||
|
p->n_player = 0;
|
||||||
|
|
||||||
socket_server_set_callback(p->server, on_connection, p);
|
socket_server_set_callback(p->server, on_connection, p);
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,8 @@ struct socket_client* socket_client_new_ipv4(struct pa_mainloop_api *m, uint32_t
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
make_tcp_socket_low_delay(c->fd);
|
||||||
|
|
||||||
sa.sin_family = AF_INET;
|
sa.sin_family = AF_INET;
|
||||||
sa.sin_port = htons(port);
|
sa.sin_port = htons(port);
|
||||||
sa.sin_addr.s_addr = htonl(address);
|
sa.sin_addr.s_addr = htonl(address);
|
||||||
|
|
@ -147,6 +149,8 @@ struct socket_client* socket_client_new_unix(struct pa_mainloop_api *m, const ch
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
make_socket_low_delay(c->fd);
|
||||||
|
|
||||||
sa.sun_family = AF_LOCAL;
|
sa.sun_family = AF_LOCAL;
|
||||||
strncpy(sa.sun_path, filename, sizeof(sa.sun_path)-1);
|
strncpy(sa.sun_path, filename, sizeof(sa.sun_path)-1);
|
||||||
sa.sun_path[sizeof(sa.sun_path) - 1] = 0;
|
sa.sun_path[sizeof(sa.sun_path) - 1] = 0;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#include "socket-server.h"
|
#include "socket-server.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
struct socket_server {
|
struct socket_server {
|
||||||
int fd;
|
int fd;
|
||||||
|
|
@ -39,6 +40,9 @@ static void callback(struct pa_mainloop_api *mainloop, void *id, int fd, enum pa
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* There should be a check for socket type here */
|
||||||
|
make_tcp_socket_low_delay(fd);
|
||||||
|
|
||||||
io = iochannel_new(s->mainloop, nfd, nfd);
|
io = iochannel_new(s->mainloop, nfd, nfd);
|
||||||
assert(io);
|
assert(io);
|
||||||
s->on_connection(s, io, s->userdata);
|
s->on_connection(s, io, s->userdata);
|
||||||
|
|
@ -78,6 +82,8 @@ struct socket_server* socket_server_new_unix(struct pa_mainloop_api *m, const ch
|
||||||
strncpy(sa.sun_path, filename, sizeof(sa.sun_path)-1);
|
strncpy(sa.sun_path, filename, sizeof(sa.sun_path)-1);
|
||||||
sa.sun_path[sizeof(sa.sun_path) - 1] = 0;
|
sa.sun_path[sizeof(sa.sun_path) - 1] = 0;
|
||||||
|
|
||||||
|
make_socket_low_delay(fd);
|
||||||
|
|
||||||
if (bind(fd, (struct sockaddr*) &sa, SUN_LEN(&sa)) < 0) {
|
if (bind(fd, (struct sockaddr*) &sa, SUN_LEN(&sa)) < 0) {
|
||||||
fprintf(stderr, "bind(): %s\n", strerror(errno));
|
fprintf(stderr, "bind(): %s\n", strerror(errno));
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -117,6 +123,8 @@ struct socket_server* socket_server_new_ipv4(struct pa_mainloop_api *m, uint32_t
|
||||||
|
|
||||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
|
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
|
||||||
fprintf(stderr, "setsockopt(): %s\n", strerror(errno));
|
fprintf(stderr, "setsockopt(): %s\n", strerror(errno));
|
||||||
|
|
||||||
|
make_tcp_socket_low_delay(fd);
|
||||||
|
|
||||||
sa.sin_family = AF_INET;
|
sa.sin_family = AF_INET;
|
||||||
sa.sin_port = htons(port);
|
sa.sin_port = htons(port);
|
||||||
|
|
|
||||||
41
src/util.c
41
src/util.c
|
|
@ -7,6 +7,8 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
#include <netinet/ip.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
|
@ -83,3 +85,42 @@ fail:
|
||||||
rmdir(dir);
|
rmdir(dir);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int make_socket_low_delay(int fd) {
|
||||||
|
int ret = 0, buf_size, priority;
|
||||||
|
|
||||||
|
assert(fd >= 0);
|
||||||
|
|
||||||
|
buf_size = 1024;
|
||||||
|
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buf_size, sizeof(buf_size)) < 0)
|
||||||
|
ret = -1;
|
||||||
|
|
||||||
|
buf_size = 1024;
|
||||||
|
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &buf_size, sizeof(buf_size)) < 0)
|
||||||
|
ret = -1;
|
||||||
|
|
||||||
|
priority = 7;
|
||||||
|
if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority)) < 0)
|
||||||
|
ret = -1;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int make_tcp_socket_low_delay(int fd) {
|
||||||
|
int ret, tos, on;
|
||||||
|
|
||||||
|
assert(fd >= 0);
|
||||||
|
|
||||||
|
ret = make_socket_low_delay(fd);
|
||||||
|
|
||||||
|
on = 1;
|
||||||
|
if (setsockopt(fd, SOL_TCP, TCP_NODELAY, &on, sizeof(on)) < 0)
|
||||||
|
ret = -1;
|
||||||
|
|
||||||
|
tos = IPTOS_LOWDELAY;
|
||||||
|
if (setsockopt(fd, SOL_IP, IP_TOS, &tos, sizeof(tos)) < 0)
|
||||||
|
ret = -1;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,7 @@ void peer_to_string(char *c, size_t l, int fd);
|
||||||
|
|
||||||
int make_secure_dir(const char* dir);
|
int make_secure_dir(const char* dir);
|
||||||
|
|
||||||
|
int make_socket_low_delay(int fd);
|
||||||
|
int make_tcp_socket_low_delay(int fd);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue