summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_unit.c (follow)
AgeCommit message (Collapse)AuthorFilesLines
2020-10-28Preserving the app port write socket.Max Romanov1-6/+6
The socket is required for intercontextual communication in multithreaded apps.
2020-10-28Libunit: waking another context with the RPC_READY message.Max Romanov1-1/+37
2020-10-28Router: introducing the PORT_ACK message.Max Romanov1-5/+32
The PORT_ACK message is the router's response to the application's NEW_PORT message. After receiving PORT_ACK, the application is safe to process requests using this port. This message avoids a racing condition when the application starts processing a request from the shared queue and sends REQ_HEADERS_ACK. The REQ_HEADERS_ACK message contains the application port ID as reply_port, which the router uses to send request data. When the application creates a new port, it immediately sends it to the main router thread. Because the request is processed outside the main thread, a racing condition can occur between the receipt of the new port in the main thread and the receipt of REQ_HEADERS_ACK in the worker router thread where the same port is specified as reply_port.
2020-10-28Libunit: releasing cached read buffers when destroying context.Max Romanov1-0/+8
2020-10-28Libunit: added a function to discern main and worker contexts.Max Romanov1-0/+11
2020-10-28Libunit: gracefully quitting a multicontext application.Max Romanov1-24/+72
2020-10-28Libunit: protecting the new mmap from being used in another thread.Max Romanov1-1/+6
Until the mmap is received by the router, only the creator thread may use this mmap, so the "mmap not found" state in the router is avoided.
2020-10-06Removing a meaningless warning message.Max Romanov1-4/+0
Data in the queue and the socket are transmitted independently; special READ_QUEUE and READ_SOCKET message types are used for synchronization. The warning was accidentally committed with changeset 1d84b9e4b459.
2020-10-01Publishing libunit's malloc() and free() wrappers for apps.Max Romanov1-49/+53
2020-09-30Fixing leakage caused by incorrect in_hash flag cleanup.Max Romanov1-1/+3
Large-bodied requests are added to the request hash to be found when the body arrives. However, changeset 1d84b9e4b459 introduced a bug: the 'in_hash' flag, used to remove the request from the hash at request release, was cleared after the first successful request lookup. As a result, the entry was never removed.
2020-09-29Wrapping libunit's malloc() and free() calls for logging purposes.Max Romanov1-51/+82
This change aids heap usage analysis in applications. The alloc and free functions are also required for lvlhash due to the upcoming threading support, because using main nxt_memalign() and nxt_free() isn't safe in a multithreaded app environment. The reason is that these functions may use thread-local structures which aren't initialized properly in applications.
2020-09-15Hardening header names comparation for grouping.Max Romanov1-10/+67
2020-09-10Fixing WebSocket frame retain function.Max Romanov1-2/+13
Some of the pointers were not adjusted after frame's memory re-allocation. Fortunately, this function was not used and the bug has no effect.
2020-08-11Fixing return value initialization.Max Romanov1-19/+25
2020-08-11Style fixes for 2 file descriptors transfer over port.Max Romanov1-35/+36
Two consecutive fd and fd2 fields replaced with array.
2020-08-11Moving file descriptor blocking to libunit.Max Romanov1-11/+39
The default libunit behavior relies on blocking the recv() call for port file descriptors, which an application may override if needed. For external applications, port file descriptors were toggled to blocking mode before the exec() call. If the exec() call failed, descriptor remained blocked, so the process hanged while trying to read from it. This patch moves file descriptor mode switch inside libunit.
2020-08-11Wrapping close() call in libunit for logging.Max Romanov1-35/+44
2020-08-11Introducing application and port shared memory queues.Max Romanov1-250/+921
The goal is to minimize the number of syscalls needed to deliver a message.
2020-08-11Port message extended to transfer 2 file descriptors.Max Romanov1-3/+16
2020-08-11Process structures refactoring in runtime and libunit.Max Romanov1-203/+93
Generic process-to-process shared memory exchange is no more required. Here, it is transformed into a router-to-application pattern. The outgoing shared memory segments collection is now the property of the application structure. The applications connect to the router only, and the process only needs to group the ports.
2020-08-11Introducing the shared application port.Max Romanov1-106/+361
This is the port shared between all application processes which use it to pass requests for processing. Using it significantly simplifies the request processing code in the router. The drawback is 2 more file descriptors per each configured application and more complex libunit message wait/read code.
2020-08-11Changing router to application shared memory exchange protocol.Max Romanov1-108/+269
The application process needs to request the shared memory segment from the router instead of the latter pushing the segment before sending a request to the application. This is required to simplify the communication between the router and the application and to prepare the router for using the application shared port and then the queue.
2020-08-11Changing router to application port exchange protocol.Max Romanov1-27/+249
The application process needs to request the port from the router instead of the latter pushing the port before sending a request to the application. This is required to simplify the communication between the router and the application and to prepare the router to use the application shared port and then the queue.
2020-08-11Adding a reference counter to the libunit port structure.Max Romanov1-342/+336
The goal is to minimize the number of (pid, id) to port hash lookups which require a library mutex lock. The response port is found once per request, while the read port is initialized at startup.
2020-08-11Libunit refactoring: port management.Max Romanov1-261/+319
- Changed the port management callbacks to notifications, which e. g. avoids the need to call the libunit function - Added context and library instance reference counts for a safer resource release - Added the router main port initialization
2020-07-21Fixed non-debug log time format in libunit.Valentin Bartenev1-0/+7
This makes log format used in libunit consistent with the daemon, where milliseconds are printed only in the debug log level. Currently a compile time switch is used, since there's no support for runtime changing of a log level for now. But in the future this should be a runtime condition, similar to nxt_log_time_handler().
2020-03-09Refactor of process management.Tiago Natel de Moura1-1/+1
The process abstraction has changed to: setup(task, process) start(task, process_data) prefork(task, process, mp) The prefork() occurs in the main process right before fork. The file src/nxt_main_process.c is completely free of process specific logic. The creation of a process now supports a PROCESS_CREATED state. The The setup() function of each process can set its state to either created or ready. If created, a MSG_PROCESS_CREATED is sent to main process, where external setup can be done (required for rootfs under container). The core processes (discovery, controller and router) doesn't need external setup, then they all proceeds to their start() function straight away. In the case of applications, the load of the module happens at the process setup() time and The module's init() function has changed to be the start() of the process. The module API has changed to: setup(task, process, conf) start(task, data) As a direct benefit of the PROCESS_CREATED message, the clone(2) of processes using pid namespaces now doesn't need to create a pipe to make the child block until parent setup uid/gid mappings nor it needs to receive the child pid.
2020-04-10Resolving a racing condition while adding ports on the app's side.Max Romanov1-3/+25
An earlier attempt (ad6265786871) to resolve this condition on the router's side added a new issue: the app could get a request before acquiring a port.
2020-04-06Fixing 'find & add' racing condition in connected ports hash.Max Romanov1-0/+3
Missing error log messages added.
2020-03-30Fixing application process infinite loop.Max Romanov1-21/+28
Main process exiting before app process init may have caused hanging.
2020-03-30Handling change file message in libunit.Max Romanov1-0/+10
This is required for proper log file rotation action.
2020-03-30Attributing libunit logging function for arguments validation.Max Romanov1-5/+7
2020-03-12Using disk file to store large request body.Max Romanov1-7/+119
This closes #386 on GitHub.
2020-03-12Introducing readline function in libunit.Max Romanov1-0/+38
Ruby and Java modules now use this function instead of own implementations.
2020-02-04Removing duplicate macro definitions.Max Romanov1-4/+0
This issue was introduced in 2c7f79bf0a1f.
2020-02-03Initializing local buffer ctx_impl field for correct release.Max Romanov1-0/+1
Uninitialized ctx_impl field may cause crash in application process. To reproduce the issue, need to trigger shared memory buffer send error on application side. In our case, send error caused by router process crash. This issue was introduced in 2c7f79bf0a1f.
2020-02-03Added missing stream argument to error message.Max Romanov1-1/+2
Found by Coverity (CID 353386).
2019-12-24Introducing port messages to notify about out of shared memory.Max Romanov1-68/+476
- OOSM (out of shared memory). Sent by application process to router when application reaches the limit of allocated shared memory and needs more. - SHM_ACK. Sent by router to application when the application's shared memory is released and the OOSM flag is enabled for the segment. This implements blocking mode (the library waits for SHM_ACK in case of out of shared memory condition and retries allocating the required memory amount) and non-blocking mode (the library notifies the application that it's out of shared memory and returns control to the application module that sets up the output queue and puts SHM_ACK in the main message loop).
2019-12-24Adding "limits/shm" configuration validation and parsing.Max Romanov1-8/+20
2019-12-24Renaming nxt_unit_mmap_buf_remove to nxt_unit_mmap_buf_unlink.Max Romanov1-7/+7
The function unchains the buffer from the buffer's linked list.
2019-12-24Using non-shared memory buffers for small messages.Max Romanov1-101/+203
Current shared memory buffer implementation uses fixed-size memory blocks, allocating at least 16384 bytes. When application sends data in a large number of small chunks, it makes sense to buffer them or use plain memory buffers to improve performance and reduce memory footprint. This patch introduces minimum size limit (1024 bytes) for shared memory buffers.
2019-11-11Fixing libunit 'off by 2' issue in library.Max Romanov1-2/+10
Name and value in each header are 0-terminated, so additional 2 bytes should be allocated for them. There were several attempts to add these 2 bytes to headers in language modules, but some modules weren't updated. Also, adding these 2 bytes is specific to the implementation which may be changed later, so extending this mechanics to modules may cause errors.
2019-10-10Style fixes.Igor Sysoev1-2/+4
2019-09-19Initial applications isolation support using Linux namespaces.Tiago de Bem Natel de Moura1-1/+1
2019-09-19Releasing WebSocket frame in case of buffer allocation failure.Max Romanov1-0/+2
Found by Coverity (CID 349456).
2019-09-18Fixing request release order to avoid crashes on exit.Max Romanov1-6/+10
Each request references the router process structure that owns all memory maps. The process structure has a reference counter; each request increases the counter to lock the structure in memory until request processing ends. Incoming and outgoing buffers reference memory maps that the process owns, so the process structure should be released only when all buffers are released to avoid invalid memory access and a crash. This describes the libunit library mechanism used for application processes. The background of this issue is as follows: The issue was found on buildbot when the router crashed during Java websocket tests. The Java application receives a notification from the master process; when the notification is processed, libunit deletes the process structure from its process hash and decrements the use counter; however, active websocket connections maintain their use counts on the process structure. After that, when the master process is stopping the application, libunit releases active websocket connections. At this point, it's important to release the connections' memory buffers before the corresponding process structure and all shared memory segments are released.
2019-09-18Reducing number of warning messages.Max Romanov1-6/+5
One alert per failed allocation is enough.
2019-09-18Protecting context structures with mutex.Max Romanov1-4/+63
By design, Unit context is created for the thread which reads messages from the router. However, Go request handlers are called in a separate goroutine that may be executed in a different thread. To avoid a racing condition, access to lists of free structures in the context should be serialized. This patch should fix random crashes in Go applications under high load. This is related to #253 and #309 issues on GitHub.
2019-08-20Introducing websocket support in router and libunit.Max Romanov1-271/+888
2019-03-11Style.Andrey Zelenkov1-2/+2