efl/src/lib/ecore_con/efl_net_server_fd.eo

167 lines
6.3 KiB
Plaintext

class Efl.Net.Server.Fd (Efl.Loop.Fd, Efl.Net.Server) {
[[A generic server based on file descriptors.
@since 1.19
]]
methods {
socket_activate {
[[If this method is called use an already activated socket.
This method allows a server to use an existing socket
received from systemd or similar system.
It will replace @Efl.Net.Server.serve, thus if this is
used, that method will return EALREADY.
\@note The parameter 'address' given to this function is
only used to validate the next socket available, it
doesn't search for a socket with the given address. Thus
the socket to be used is the next unused and orders
matter is using multiple servers!
\@note subclasses must validate the socket and return
EINVAL prior to call the base class with
Efl.Object.super. They must also emit "serving" when
ready, for instance stream protocols may need to check
for listening and if not try to listen. Usually they
will also query getsockname() and set
@Efl.Net.Server.address.
Errors:
- EALREADY: already have a socket, either from
previous @.socket_activate or
@Efl.Net.Server.serve. Usually represents a
programming error.
- ENOENT: no sockets received from process manager
(ie: systemd). Usually this is not a fatal error,
just proceed by calling @Efl.Net.Server.serve
- EINVAL: the socket received is not of the correct
family, type or protocol. Usually this means a
configuration mismatch with the order of server
creation and calls to socket_activate. The
systemd.socket entries must match the order in your
application.
]]
params {
address: string; [[The address to validate the next available socket. It doesn't serve as search, only as validation!]]
}
return: Eina.Error; [[0 on success, ENOENT if no socket is available or EALREADY if already have a socket]]
}
@property family {
[[The address family (AF_*) family of this socket.
It will be one of AF_INET (IPv4), AF_INET6 (IPv6),
AF_UNIX...
It must be set before the @Efl.Loop.Fd.fd.set is called
with a valid file descriptor.
]]
get { }
set @protected { }
values {
family: int; [[Socket address family]]
}
}
@property close_on_exec {
[[Controls Close-on-Exec() using FD_CLOEXEC.
Children socket will inherit the server's setting by
default. One can change the behavior using each instance
@Efl.Io.Closer.close_on_exec.set.
]]
get { }
set {
return: bool (false); [[$true on success, $false otherwise]]
}
values {
close_on_exec: bool; [[If $true close on exec will be used, $false otherwise]]
}
}
@property reuse_address {
[[Controls address reuse() using SO_REUSEADDR]]
get { }
set {
return: bool (false); [[$true on success, $false otherwise]]
}
values {
reuse_address: bool; [[If $true the server will reuse the address, $false otherwise]]
}
}
@property reuse_port {
[[Controls port reuse() using SO_REUSEPORT (since linux 3.9)]]
get { }
set {
return: bool (false); [[$true on success, $false otherwise]]
}
values {
reuse_port: bool; [[If $true the server will reuse the port, $false otherwise]]
}
}
process_incoming_data @protected {
[[When the socket has data to be read, process it.
By default this method will call accept() and then
decide if @.client_add or @.client_reject must be
executed, however it may be replaced with something
else, such as in SOCK_DGRAM (UDP) there is no accept(),
only recvfrom().
It is called straight from @Efl.Loop.Fd "read" event
handler and is provided as a method to allow easy
extending of the class for various purposes.
]]
}
client_add @protected @virtual_pure {
[[Accept a new client, should emit "client,add".
Remember to create the client object with a callback to
EFL_IO_CLOSER_EVENT_CLOSED during the construction and
decrease @Efl.Net.Server.clients_count as well as unref
the client and remove yourself as parent.
The new clients should have the server as parent and
increase the @Efl.Net.Server.clients_count.
Whenever this function fails, it must close the given
client file descriptor.
]]
params {
client_fd: int; [[The file descriptor of the client socket. It comes preconfigured with close_on_exec. On failure, remember to close this socket]]
}
}
client_reject @protected @virtual_pure {
[[Reject a new client, should emit "client,rejected".
Must always close the client socket when it's done.
]]
params {
client_fd: int; [[The file descriptor of the client socket. It comes preconfigured with close_on_exec and should be closed once it's not needed anymore]]
}
}
}
implements {
Efl.Object.finalize;
Efl.Object.constructor;
Efl.Object.destructor;
Efl.Loop.Fd.fd { set; }
Efl.Net.Server.address { get; set; }
Efl.Net.Server.clients_count { get; set; }
Efl.Net.Server.clients_limit { get; set; }
Efl.Net.Server.serving { get; set; }
Efl.Net.Server.serve;
Efl.Net.Server.client_announce;
}
}