1/*
2 This file is part of Mtproto-proxy Library.
3
4 Mtproto-proxy Library is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation, either version 2 of the License, or
7 (at your option) any later version.
8
9 Mtproto-proxy Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with Mtproto-proxy Library. If not, see <http://www.gnu.org/licenses/>.
16
17 Copyright 2015-2016 Telegram Messenger Inc
18 2015-2016 Vitaly Valtman
19
20*/
21#define _FILE_OFFSET_BITS 64
22#include <assert.h>
23#include <unistd.h>
24#include <stdlib.h>
25#include <string.h>
26
27#include "net/net-thread.h"
28#include "net/net-connections.h"
29#include "net/net-msg.h"
30#include "net/net-msg-buffers.h"
31#include "net/net-tcp-rpc-client.h"
32#include "net/net-tcp-rpc-common.h"
33#include "net/net-tcp-rpc-server.h"
34
35#include "common/mp-queue.h"
36#include "common/kprintf.h"
37#include "common/server-functions.h"
38
39#define NEV_TCP_CONN_READY 1
40#define NEV_TCP_CONN_CLOSE 2
41#define NEV_TCP_CONN_ALARM 3
42#define NEV_TCP_CONN_WAKEUP 4
43
44struct notification_event {
45 int type;
46 void *who;
47};
48
49void run_notification_event (struct notification_event *ev) {
50 connection_job_t C = ev->who;
51 switch (ev->type) {
52 case NEV_TCP_CONN_READY:
53 if (TCP_RPCC_FUNC(C)->rpc_ready && TCP_RPCC_FUNC(C)->rpc_ready (C) < 0) {
54 fail_connection (C, -8);
55 }
56 job_decref (JOB_REF_PASS (C));
57 break;
58 case NEV_TCP_CONN_CLOSE:
59 TCP_RPCC_FUNC(C)->rpc_close (C, 0);
60 job_decref (JOB_REF_PASS (C));
61 break;
62 case NEV_TCP_CONN_ALARM:
63 TCP_RPCC_FUNC(C)->rpc_alarm (C);
64 job_decref (JOB_REF_PASS (C));
65 break;
66 case NEV_TCP_CONN_WAKEUP:
67 TCP_RPCC_FUNC(C)->rpc_wakeup (C);
68 job_decref (JOB_REF_PASS (C));
69 break;
70 default:
71 assert (0);
72 }
73 free (ev);
74}
75
76struct notification_event_job_extra {
77 struct mp_queue *queue;
78};
79static job_t notification_job;
80
81int notification_event_run (job_t job, int op, struct job_thread *JT) {
82 if (op != JS_RUN) {
83 return JOB_ERROR;
84 }
85 struct notification_event_job_extra *E = (void *)job->j_custom;
86
87 while (1) {
88 struct notification_event *ev = mpq_pop_nw (E->queue, 4);
89 if (!ev) { break; }
90
91 run_notification_event (ev);
92 }
93
94 return 0;
95}
96
97void notification_event_job_create (void) {
98 notification_job = create_async_job (notification_event_run, JSC_ALLOW (JC_ENGINE, JS_RUN) | JSC_ALLOW (JC_ENGINE, JS_FINISH), 0, sizeof (struct notification_event_job_extra), 0, JOB_REF_NULL);
99
100 struct notification_event_job_extra *E = (void *)notification_job->j_custom;
101 E->queue = alloc_mp_queue_w ();
102
103 unlock_job (JOB_REF_CREATE_PASS (notification_job));
104}
105
106void notification_event_insert_conn (connection_job_t C, int type) {
107 struct notification_event *ev = malloc (sizeof (*ev));
108 ev->who = job_incref (C);
109 ev->type = type;
110
111 struct notification_event_job_extra *E = (void *)notification_job->j_custom;
112 mpq_push_w (E->queue, ev, 0);
113 job_signal (JOB_REF_CREATE_PASS (notification_job), JS_RUN);
114}
115
116void notification_event_insert_tcp_conn_close (connection_job_t C) {
117 notification_event_insert_conn (C, NEV_TCP_CONN_CLOSE);
118}
119
120void notification_event_insert_tcp_conn_ready (connection_job_t C) {
121 notification_event_insert_conn (C, NEV_TCP_CONN_READY);
122}
123
124void notification_event_insert_tcp_conn_alarm (connection_job_t C) {
125 notification_event_insert_conn (C, NEV_TCP_CONN_ALARM);
126}
127
128void notification_event_insert_tcp_conn_wakeup (connection_job_t C) {
129 notification_event_insert_conn (C, NEV_TCP_CONN_WAKEUP);
130}
131