71
76
extern Export* dexit_trap;
72
77
extern Export* dmonitor_p_trap;
81
#define ERTS_DIST_OP_DATA_INIT(DODP, PROC, LCKS, DEP, DPRT) \
83
(DODP)->proc = (PROC); \
84
(DODP)->lcks = (LCKS); \
85
(DODP)->dep = (DEP); \
86
(DODP)->dprt = (DPRT); \
89
ERTS_GLB_INLINE void erts_dist_op_prepare(ErtsDistOpData *,
93
ERTS_GLB_INLINE void erts_dist_op_finalize(ErtsDistOpData *);
95
#if ERTS_GLB_INLINE_INCL_FUNC_DEF
98
erts_dist_op_prepare(ErtsDistOpData *dodp,
101
ErtsProcLocks proc_locks)
104
erts_smp_dist_entry_lock(dep);
106
dprt = erts_de2port(dep, proc, proc_locks);
108
dprt = erts_id2port(dep->cid, NULL, 0);
110
ERTS_DIST_OP_DATA_INIT(dodp, proc, proc_locks, dep, dprt);
114
erts_dist_op_finalize(ErtsDistOpData *dodp)
117
erts_port_release(dodp->dprt);
118
erts_smp_dist_entry_unlock(dodp->dep);
123
extern int erts_dist_link(ErtsDistOpData *, Eterm, Eterm);
124
extern int erts_dist_send(ErtsDistOpData *, Eterm, Eterm);
125
extern int erts_dist_exit_tt(ErtsDistOpData *, Eterm, Eterm, Eterm, Eterm);
126
extern int erts_dist_unlink(ErtsDistOpData *, Eterm, Eterm);
127
extern int erts_dist_reg_send(ErtsDistOpData *, Eterm, Eterm);
128
extern int erts_dist_group_leader(ErtsDistOpData *, Eterm, Eterm);
129
extern int erts_dist_exit(ErtsDistOpData *, Eterm, Eterm, Eterm);
130
extern int erts_dist_exit2(ErtsDistOpData *, Eterm, Eterm, Eterm);
131
extern int erts_dist_demonitor(ErtsDistOpData *, Eterm, Eterm, Eterm, int);
132
extern int erts_dist_monitor(ErtsDistOpData *, Eterm, Eterm, Eterm);
133
extern int erts_dist_m_exit(ErtsDistOpData *, Eterm, Eterm, Eterm, Eterm);
94
#define ERTS_DE_IS_NOT_CONNECTED(DEP) \
95
(ERTS_SMP_LC_ASSERT(erts_lc_rwmtx_is_rlocked(&(DEP)->rwmtx) \
96
|| erts_lc_rwmtx_is_rwlocked(&(DEP)->rwmtx)), \
97
(is_nil((DEP)->cid) || ((DEP)->status & ERTS_DE_SFLG_EXITING)))
99
#define ERTS_DE_IS_CONNECTED(DEP) \
100
(!ERTS_DE_IS_NOT_CONNECTED((DEP)))
103
extern int erts_is_alive;
106
* erts_dsig_prepare() prepares a send of a distributed signal.
107
* One of the values defined below are returned. If the returned
108
* value is another than ERTS_DSIG_PREP_CONNECTED, the
109
* distributed signal cannot be sent before apropriate actions
110
* have been taken. Apropriate actions would typically be setting
114
/* Connected; signal can be sent. */
115
#define ERTS_DSIG_PREP_CONNECTED 0
116
/* Not connected; connection needs to be set up. */
117
#define ERTS_DSIG_PREP_NOT_CONNECTED 1
118
/* Caller would be suspended on send operation. */
119
#define ERTS_DSIG_PREP_WOULD_SUSPEND 2
120
/* System not alive (distributed) */
121
#define ERTS_DSIG_PREP_NOT_ALIVE 3
123
ERTS_GLB_INLINE int erts_dsig_prepare(ErtsDSigData *,
130
void erts_schedule_dist_command(Port *, DistEntry *);
132
#if ERTS_GLB_INLINE_INCL_FUNC_DEF
135
erts_dsig_prepare(ErtsDSigData *dsdp,
138
ErtsDSigPrepLock dspl,
143
return ERTS_DSIG_PREP_NOT_ALIVE;
145
return ERTS_DSIG_PREP_NOT_CONNECTED;
146
if (dspl == ERTS_DSP_RWLOCK)
147
erts_smp_de_rwlock(dep);
149
erts_smp_de_rlock(dep);
150
if (ERTS_DE_IS_NOT_CONNECTED(dep)) {
151
failure = ERTS_DSIG_PREP_NOT_CONNECTED;
155
failure = ERTS_DSIG_PREP_CONNECTED;
156
erts_smp_spin_lock(&dep->qlock);
157
if (dep->qflgs & ERTS_DE_QFLG_BUSY)
158
failure = ERTS_DSIG_PREP_WOULD_SUSPEND;
159
erts_smp_spin_unlock(&dep->qlock);
160
if (failure == ERTS_DSIG_PREP_WOULD_SUSPEND)
165
dsdp->cid = dep->cid;
166
dsdp->connection_id = dep->connection_id;
167
dsdp->no_suspend = no_suspend;
168
if (dspl == ERTS_DSP_NO_LOCK)
169
erts_smp_de_runlock(dep);
170
return ERTS_DSIG_PREP_CONNECTED;
173
if (dspl == ERTS_DSP_RWLOCK)
174
erts_smp_de_rwunlock(dep);
176
erts_smp_de_runlock(dep);
182
void erts_schedule_dist_command(Port *prt, DistEntry *dist_entry)
188
ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(prt));
189
ASSERT((erts_port_status_get(prt) & ERTS_PORT_SFLGS_DEAD) == 0);
190
ASSERT(prt->dist_entry);
192
dep = prt->dist_entry;
197
ERTS_SMP_LC_ASSERT(erts_lc_rwmtx_is_rlocked(&dist_entry->rwmtx)
198
|| erts_lc_rwmtx_is_rwlocked(&dist_entry->rwmtx));
199
ASSERT(is_internal_port(dist_entry->cid));
205
if (!erts_smp_atomic_xchg(&dep->dist_cmd_scheduled, 1)) {
206
(void) erts_port_task_schedule(id,
208
ERTS_PORT_TASK_DIST_CMD,
221
ERTS_GLB_INLINE void erts_remove_dist_link(ErtsDistLinkData *,
225
ERTS_GLB_INLINE int erts_was_dist_link_removed(ErtsDistLinkData *);
226
ERTS_GLB_INLINE void erts_destroy_dist_link(ErtsDistLinkData *);
228
#if ERTS_GLB_INLINE_INCL_FUNC_DEF
231
erts_remove_dist_link(ErtsDistLinkData *dldp,
236
erts_smp_de_links_lock(dep);
237
dldp->d_lnk = erts_lookup_link(dep->nlinks, lid);
239
dldp->d_sub_lnk = NULL;
241
dldp->d_sub_lnk = erts_remove_link(&ERTS_LINK_ROOT(dldp->d_lnk), rid);
242
dldp->d_lnk = (ERTS_LINK_ROOT(dldp->d_lnk)
244
: erts_remove_link(&dep->nlinks, lid));
246
erts_smp_de_links_unlock(dep);
250
erts_was_dist_link_removed(ErtsDistLinkData *dldp)
252
return dldp->d_sub_lnk != NULL;
256
erts_destroy_dist_link(ErtsDistLinkData *dldp)
259
erts_destroy_link(dldp->d_lnk);
261
erts_destroy_link(dldp->d_sub_lnk);
267
* erts_dsig_send_* return values.
269
#define ERTS_DSIG_SEND_OK 0
270
#define ERTS_DSIG_SEND_YIELD 1
272
extern int erts_dsig_send_link(ErtsDSigData *, Eterm, Eterm);
273
extern int erts_dsig_send_msg(ErtsDSigData *, Eterm, Eterm);
274
extern int erts_dsig_send_exit_tt(ErtsDSigData *, Eterm, Eterm, Eterm, Eterm);
275
extern int erts_dsig_send_unlink(ErtsDSigData *, Eterm, Eterm);
276
extern int erts_dsig_send_reg_msg(ErtsDSigData *, Eterm, Eterm);
277
extern int erts_dsig_send_group_leader(ErtsDSigData *, Eterm, Eterm);
278
extern int erts_dsig_send_exit(ErtsDSigData *, Eterm, Eterm, Eterm);
279
extern int erts_dsig_send_exit2(ErtsDSigData *, Eterm, Eterm, Eterm);
280
extern int erts_dsig_send_demonitor(ErtsDSigData *, Eterm, Eterm, Eterm, int);
281
extern int erts_dsig_send_monitor(ErtsDSigData *, Eterm, Eterm, Eterm);
282
extern int erts_dsig_send_m_exit(ErtsDSigData *, Eterm, Eterm, Eterm, Eterm);
284
extern int erts_dist_command(Port *prt, int reds);
285
extern void erts_dist_port_not_busy(Port *prt);
286
extern void erts_kill_dist_connection(DistEntry *dep, Uint32);
135
288
extern Uint erts_dist_cache_size(void);
136
extern int erts_is_alive(void);