• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

krakjoe / parallel / 20458908037

23 Dec 2025 11:00AM UTC coverage: 93.79% (-1.2%) from 94.99%
20458908037

Pull #363

github

web-flow
Merge a62b0c626 into 3c00d4ed1
Pull Request #363: Fix cache key collision

7 of 9 new or added lines in 1 file covered. (77.78%)

31 existing lines in 4 files now uncovered.

2764 of 2947 relevant lines covered (93.79%)

749.68 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.0
/src/dependencies.c
1
/*
2
  +----------------------------------------------------------------------+
3
  | parallel                                                             |
4
  +----------------------------------------------------------------------+
5
  | Copyright (c) Joe Watkins 2019-2024                                  |
6
  +----------------------------------------------------------------------+
7
  | This source file is subject to version 3.01 of the PHP license,      |
8
  | that is bundled with this package in the file LICENSE, and is        |
9
  | available through the world-wide-web at the following url:           |
10
  | http://www.php.net/license/3_01.txt                                  |
11
  | If you did not receive a copy of the PHP license and are unable to   |
12
  | obtain it through the world-wide-web, please send a note to          |
13
  | license@php.net so we can mail you a copy immediately.               |
14
  +----------------------------------------------------------------------+
15
  | Author: krakjoe                                                      |
16
  +----------------------------------------------------------------------+
17
 */
18
#ifndef HAVE_PARALLEL_DEPENDENCIES
19
#define HAVE_PARALLEL_DEPENDENCIES
20

21
#include "parallel.h"
22

23
static struct {
24
        pthread_mutex_t mutex;
25
        HashTable       table;
26
} php_parallel_dependencies_map;
27

28
#define PDM(e) php_parallel_dependencies_map.e
29

30
TSRM_TLS struct {
31
        HashTable activated;
32
        HashTable used;
33
} php_parallel_dependencies_globals;
34

35
#define PDG(e) php_parallel_dependencies_globals.e
36

37
/* {{{ */
38
static zend_always_inline void php_parallel_dependencies_load_globals_vars(const zend_function *function)
286✔
39
{
40
        zend_string **variables = function->op_array.vars;
286✔
41
        int           it = 0, end = function->op_array.last_var;
286✔
42

43
        while (it < end) {
600✔
44
                zend_is_auto_global(variables[it]);
314✔
45
                it++;
314✔
46
        }
47
} /* }}} */
48

49
/* {{{ */
50
static zend_always_inline void php_parallel_dependencies_load_globals_literals(const zend_function *function)
286✔
51
{
52
        zval *literals = function->op_array.literals;
286✔
53
        int   it = 0, end = function->op_array.last_literal;
286✔
54

55
        while (it < end) {
1,568✔
56
                if (Z_TYPE(literals[it]) == IS_STRING) {
1,282✔
57
                        zend_is_auto_global(Z_STR(literals[it]));
728✔
58
                }
59
                it++;
1,282✔
60
        }
61
} /* }}} */
62

63
/* {{{ */
64
static void php_parallel_dependencies_load_globals(const zend_function *function)
332✔
65
{
66
        if (zend_hash_index_exists(&PDG(activated), (zend_ulong)function->op_array.opcodes)) {
332✔
67
                return;
68
        }
69

70
        php_parallel_dependencies_load_globals_vars(function);
286✔
71
        php_parallel_dependencies_load_globals_literals(function);
286✔
72

73
#if PHP_VERSION_ID >= 80100
74
        if (function->op_array.dynamic_func_defs) {
286✔
75
                uint32_t it = 0, end = function->op_array.num_dynamic_func_defs;
24✔
76

77
                while (it < end) {
52✔
78
                        php_parallel_dependencies_load_globals((zend_function *)function->op_array.dynamic_func_defs[it]);
28✔
79
                        it++;
28✔
80
                }
81
        }
82
#endif
83

84
        zend_hash_index_add_empty_element(&PDG(activated), (zend_ulong)function->op_array.opcodes);
286✔
85
} /* }}} */
86

87
void php_parallel_dependencies_store(const zend_function *function)
314✔
88
{ /* {{{ */
89
#if PHP_VERSION_ID < 80100
90
        HashTable dependencies;
91

92
        pthread_mutex_lock(&PDM(mutex));
93

94
        if (zend_hash_index_exists(&PDM(table), (zend_ulong)function->op_array.opcodes)) {
95
                pthread_mutex_unlock(&PDM(mutex));
96
                return;
97
        }
98

99
        memset(&dependencies, 0, sizeof(HashTable));
100
        {
101
                zend_op *opline = function->op_array.opcodes, *end = opline + function->op_array.last;
102

103
                while (opline < end) {
104
                        if (opline->opcode == ZEND_DECLARE_LAMBDA_FUNCTION) {
105
                                zend_string   *key;
106
                                zend_function *dependency;
107

108
                                PARALLEL_COPY_OPLINE_TO_FUNCTION(function, opline, &key, &dependency);
109

110
                                dependency = php_parallel_copy_function(dependency, 1);
111

112
                                if (dependencies.nNumUsed == 0) {
113
                                        zend_hash_init(&dependencies, 8, NULL, NULL, 1);
114
                                }
115

116
                                zend_hash_add_ptr(&dependencies, php_parallel_copy_string_interned(key), dependency);
117

118
                                php_parallel_dependencies_store(dependency);
119
                        }
120
                        opline++;
121
                }
122
        }
123

124
        zend_hash_index_add_mem(&PDM(table), (zend_ulong)function->op_array.opcodes, &dependencies, sizeof(HashTable));
125

126
        pthread_mutex_unlock(&PDM(mutex));
127
#endif
128
} /* }}} */
314✔
129

130
void php_parallel_dependencies_load(const zend_function *function)
304✔
131
{ /* {{{ */
132
#if PHP_VERSION_ID < 80100
133
        HashTable     *dependencies;
134
        zend_string   *key;
135
        zend_function *dependency;
136
#endif
137

138
        php_parallel_dependencies_load_globals(function);
304✔
139

140
#if PHP_VERSION_ID < 80100
141
        pthread_mutex_lock(&PDM(mutex));
142
        dependencies = zend_hash_index_find_ptr(&PDM(table), (zend_ulong)function->op_array.opcodes);
143
        pthread_mutex_unlock(&PDM(mutex));
144

145
        /* read only table */
146

147
        if (!dependencies || !dependencies->nNumUsed) {
148
                return;
149
        }
150

151
        ZEND_HASH_FOREACH_STR_KEY_PTR(dependencies, key, dependency)
152
        {
153
                if (!zend_hash_exists(EG(function_table), key)) {
154
                        zend_op_array *used = (zend_op_array *)php_parallel_copy_function(dependency, 0);
155

156
                        zend_hash_add_ptr(EG(function_table), key, used);
157

158
                        ZEND_MAP_PTR_NEW(used->run_time_cache);
159

160
                        zend_hash_add_empty_element(&PDG(used), key);
161
                }
162
        }
163
        ZEND_HASH_FOREACH_END();
164
#endif
165
} /* }}} */
304✔
166

UNCOV
167
static void php_parallel_dependencies_dtor(zval *zv)
×
168
{ /* {{{ */
UNCOV
169
        zend_hash_destroy(Z_PTR_P(zv));
×
UNCOV
170
        pefree(Z_PTR_P(zv), 1);
×
UNCOV
171
} /* }}} */
×
172

173
PHP_RINIT_FUNCTION(PARALLEL_DEPENDENCIES)
590✔
174
{
175
        zend_hash_init(&PDG(activated), 32, NULL, NULL, 0);
590✔
176
        zend_hash_init(&PDG(used), 32, NULL, NULL, 0);
590✔
177

178
        return SUCCESS;
590✔
179
}
180

181
PHP_RSHUTDOWN_FUNCTION(PARALLEL_DEPENDENCIES)
590✔
182
{
183
        zend_string *key;
590✔
184

185
        zend_hash_destroy(&PDG(activated));
590✔
186
        ZEND_HASH_FOREACH_STR_KEY(&PDG(used), key) { zend_hash_del(EG(function_table), key); }
590✔
187
        ZEND_HASH_FOREACH_END();
188
        zend_hash_destroy(&PDG(used));
590✔
189

190
        return SUCCESS;
590✔
191
}
192

193
PHP_MINIT_FUNCTION(PARALLEL_DEPENDENCIES)
328✔
194
{
195
        php_parallel_mutex_init(&PDM(mutex), 1);
328✔
196

197
        zend_hash_init(&PDM(table), 32, NULL, php_parallel_dependencies_dtor, 1);
328✔
198

199
        return SUCCESS;
328✔
200
}
201

202
PHP_MSHUTDOWN_FUNCTION(PARALLEL_DEPENDENCIES)
328✔
203
{
204
        zend_hash_destroy(&PDM(table));
328✔
205
        php_parallel_mutex_destroy(&PDM(mutex));
328✔
206

207
        return SUCCESS;
328✔
208
}
209
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc