diff options
Diffstat (limited to 'src/linda.cpp')
-rw-r--r-- | src/linda.cpp | 256 |
1 files changed, 128 insertions, 128 deletions
diff --git a/src/linda.cpp b/src/linda.cpp index 67a97c2..f88158a 100644 --- a/src/linda.cpp +++ b/src/linda.cpp | |||
@@ -127,11 +127,11 @@ template <bool OPT> | |||
127 | 127 | ||
128 | // ################################################################################################# | 128 | // ################################################################################################# |
129 | 129 | ||
130 | static void check_key_types(lua_State* L, int start_, int end_) | 130 | static void check_key_types(lua_State* L_, int start_, int end_) |
131 | { | 131 | { |
132 | for (int i{ start_ }; i <= end_; ++i) | 132 | for (int i{ start_ }; i <= end_; ++i) |
133 | { | 133 | { |
134 | LuaType const t{ lua_type_as_enum(L, i) }; | 134 | LuaType const t{ lua_type_as_enum(L_, i) }; |
135 | switch (t) | 135 | switch (t) |
136 | { | 136 | { |
137 | case LuaType::BOOLEAN: | 137 | case LuaType::BOOLEAN: |
@@ -144,25 +144,25 @@ static void check_key_types(lua_State* L, int start_, int end_) | |||
144 | static constexpr std::array<std::reference_wrapper<UniqueKey const>, 3> kKeysToCheck{ kLindaBatched, kCancelError, kNilSentinel }; | 144 | static constexpr std::array<std::reference_wrapper<UniqueKey const>, 3> kKeysToCheck{ kLindaBatched, kCancelError, kNilSentinel }; |
145 | for (UniqueKey const& key : kKeysToCheck) | 145 | for (UniqueKey const& key : kKeysToCheck) |
146 | { | 146 | { |
147 | if (key.equals(L, i)) | 147 | if (key.equals(L_, i)) |
148 | { | 148 | { |
149 | raise_luaL_error(L, "argument #%d: can't use %s as a key", i, key.m_debugName); | 149 | raise_luaL_error(L_, "argument #%d: can't use %s as a key", i, key.m_debugName); |
150 | break; | 150 | break; |
151 | } | 151 | } |
152 | } | 152 | } |
153 | } | 153 | } |
154 | break; | 154 | break; |
155 | } | 155 | } |
156 | raise_luaL_error(L, "argument #%d: invalid key type (not a boolean, string, number or light userdata)", i); | 156 | raise_luaL_error(L_, "argument #%d: invalid key type (not a boolean, string, number or light userdata)", i); |
157 | } | 157 | } |
158 | } | 158 | } |
159 | 159 | ||
160 | // ################################################################################################# | 160 | // ################################################################################################# |
161 | 161 | ||
162 | // used to perform all linda operations that access keepers | 162 | // used to perform all linda operations that access keepers |
163 | int Linda::ProtectedCall(lua_State* L, lua_CFunction f_) | 163 | int Linda::ProtectedCall(lua_State* L_, lua_CFunction f_) |
164 | { | 164 | { |
165 | Linda* const linda{ ToLinda<false>(L, 1) }; | 165 | Linda* const linda{ ToLinda<false>(L_, 1) }; |
166 | 166 | ||
167 | // acquire the keeper | 167 | // acquire the keeper |
168 | Keeper* const K{ linda->acquireKeeper() }; | 168 | Keeper* const K{ linda->acquireKeeper() }; |
@@ -170,13 +170,13 @@ int Linda::ProtectedCall(lua_State* L, lua_CFunction f_) | |||
170 | if (KL == nullptr) | 170 | if (KL == nullptr) |
171 | return 0; | 171 | return 0; |
172 | // if we didn't do anything wrong, the keeper stack should be clean | 172 | // if we didn't do anything wrong, the keeper stack should be clean |
173 | LUA_ASSERT(L, lua_gettop(KL) == 0); | 173 | LUA_ASSERT(L_, lua_gettop(KL) == 0); |
174 | 174 | ||
175 | // push the function to be called and move it before the arguments | 175 | // push the function to be called and move it before the arguments |
176 | lua_pushcfunction(L, f_); | 176 | lua_pushcfunction(L_, f_); |
177 | lua_insert(L, 1); | 177 | lua_insert(L_, 1); |
178 | // do a protected call | 178 | // do a protected call |
179 | int const rc{ lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0) }; | 179 | int const rc{ lua_pcall(L_, lua_gettop(L_) - 1, LUA_MULTRET, 0) }; |
180 | // whatever happens, the keeper state stack must be empty when we are done | 180 | // whatever happens, the keeper state stack must be empty when we are done |
181 | lua_settop(KL, 0); | 181 | lua_settop(KL, 0); |
182 | 182 | ||
@@ -186,10 +186,10 @@ int Linda::ProtectedCall(lua_State* L, lua_CFunction f_) | |||
186 | // if there was an error, forward it | 186 | // if there was an error, forward it |
187 | if (rc != LUA_OK) | 187 | if (rc != LUA_OK) |
188 | { | 188 | { |
189 | raise_lua_error(L); | 189 | raise_lua_error(L_); |
190 | } | 190 | } |
191 | // return whatever the actual operation provided | 191 | // return whatever the actual operation provided |
192 | return lua_gettop(L); | 192 | return lua_gettop(L_); |
193 | } | 193 | } |
194 | 194 | ||
195 | // ################################################################################################# | 195 | // ################################################################################################# |
@@ -205,27 +205,27 @@ int Linda::ProtectedCall(lua_State* L, lua_CFunction f_) | |||
205 | */ | 205 | */ |
206 | LUAG_FUNC(linda_send) | 206 | LUAG_FUNC(linda_send) |
207 | { | 207 | { |
208 | auto send = [](lua_State* L) | 208 | auto send = [](lua_State* L_) |
209 | { | 209 | { |
210 | Linda* const linda{ ToLinda<false>(L, 1) }; | 210 | Linda* const linda{ ToLinda<false>(L_, 1) }; |
211 | std::chrono::time_point<std::chrono::steady_clock> until{ std::chrono::time_point<std::chrono::steady_clock>::max() }; | 211 | std::chrono::time_point<std::chrono::steady_clock> until{ std::chrono::time_point<std::chrono::steady_clock>::max() }; |
212 | int key_i{ 2 }; // index of first key, if timeout not there | 212 | int key_i{ 2 }; // index of first key, if timeout not there |
213 | 213 | ||
214 | if (lua_type(L, 2) == LUA_TNUMBER) // we don't want to use lua_isnumber() because of autocoercion | 214 | if (lua_type(L_, 2) == LUA_TNUMBER) // we don't want to use lua_isnumber() because of autocoercion |
215 | { | 215 | { |
216 | lua_Duration const duration{ lua_tonumber(L, 2) }; | 216 | lua_Duration const duration{ lua_tonumber(L_, 2) }; |
217 | if (duration.count() >= 0.0) | 217 | if (duration.count() >= 0.0) |
218 | { | 218 | { |
219 | until = std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(duration); | 219 | until = std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(duration); |
220 | } | 220 | } |
221 | ++key_i; | 221 | ++key_i; |
222 | } | 222 | } |
223 | else if (lua_isnil(L, 2)) // alternate explicit "infinite timeout" by passing nil before the key | 223 | else if (lua_isnil(L_, 2)) // alternate explicit "infinite timeout" by passing nil before the key |
224 | { | 224 | { |
225 | ++key_i; | 225 | ++key_i; |
226 | } | 226 | } |
227 | 227 | ||
228 | bool const as_nil_sentinel{ kNilSentinel.equals(L, key_i) }; // if not nullptr, send() will silently send a single nil if nothing is provided | 228 | bool const as_nil_sentinel{ kNilSentinel.equals(L_, key_i) }; // if not nullptr, send() will silently send a single nil if nothing is provided |
229 | if (as_nil_sentinel) | 229 | if (as_nil_sentinel) |
230 | { | 230 | { |
231 | // the real key to send data to is after the kNilSentinel marker | 231 | // the real key to send data to is after the kNilSentinel marker |
@@ -233,31 +233,31 @@ LUAG_FUNC(linda_send) | |||
233 | } | 233 | } |
234 | 234 | ||
235 | // make sure the key is of a valid type | 235 | // make sure the key is of a valid type |
236 | check_key_types(L, key_i, key_i); | 236 | check_key_types(L_, key_i, key_i); |
237 | 237 | ||
238 | STACK_GROW(L, 1); | 238 | STACK_GROW(L_, 1); |
239 | 239 | ||
240 | // make sure there is something to send | 240 | // make sure there is something to send |
241 | if (lua_gettop(L) == key_i) | 241 | if (lua_gettop(L_) == key_i) |
242 | { | 242 | { |
243 | if (as_nil_sentinel) | 243 | if (as_nil_sentinel) |
244 | { | 244 | { |
245 | // send a single nil if nothing is provided | 245 | // send a single nil if nothing is provided |
246 | kNilSentinel.pushKey(L); | 246 | kNilSentinel.pushKey(L_); |
247 | } | 247 | } |
248 | else | 248 | else |
249 | { | 249 | { |
250 | raise_luaL_error(L, "no data to send"); | 250 | raise_luaL_error(L_, "no data to send"); |
251 | } | 251 | } |
252 | } | 252 | } |
253 | 253 | ||
254 | // convert nils to some special non-nil sentinel in sent values | 254 | // convert nils to some special non-nil sentinel in sent values |
255 | keeper_toggle_nil_sentinels(L, key_i + 1, LookupMode::ToKeeper); | 255 | keeper_toggle_nil_sentinels(L_, key_i + 1, LookupMode::ToKeeper); |
256 | bool ret{ false }; | 256 | bool ret{ false }; |
257 | CancelRequest cancel{ CancelRequest::None }; | 257 | CancelRequest cancel{ CancelRequest::None }; |
258 | KeeperCallResult pushed; | 258 | KeeperCallResult pushed; |
259 | { | 259 | { |
260 | Lane* const lane{ kLanePointerRegKey.readLightUserDataValue<Lane>(L) }; | 260 | Lane* const lane{ kLanePointerRegKey.readLightUserDataValue<Lane>(L_) }; |
261 | Keeper* const K{ linda->whichKeeper() }; | 261 | Keeper* const K{ linda->whichKeeper() }; |
262 | KeeperState const KL{ K ? K->L : nullptr }; | 262 | KeeperState const KL{ K ? K->L : nullptr }; |
263 | if (KL == nullptr) | 263 | if (KL == nullptr) |
@@ -279,15 +279,15 @@ LUAG_FUNC(linda_send) | |||
279 | } | 279 | } |
280 | 280 | ||
281 | STACK_CHECK(KL, 0); | 281 | STACK_CHECK(KL, 0); |
282 | pushed = keeper_call(linda->U, KL, KEEPER_API(send), L, linda, key_i); | 282 | pushed = keeper_call(linda->U, KL, KEEPER_API(send), L_, linda, key_i); |
283 | if (!pushed.has_value()) | 283 | if (!pushed.has_value()) |
284 | { | 284 | { |
285 | break; | 285 | break; |
286 | } | 286 | } |
287 | LUA_ASSERT(L, pushed.value() == 1); | 287 | LUA_ASSERT(L_, pushed.value() == 1); |
288 | 288 | ||
289 | ret = lua_toboolean(L, -1) ? true : false; | 289 | ret = lua_toboolean(L_, -1) ? true : false; |
290 | lua_pop(L, 1); | 290 | lua_pop(L_, 1); |
291 | 291 | ||
292 | if (ret) | 292 | if (ret) |
293 | { | 293 | { |
@@ -309,9 +309,9 @@ LUAG_FUNC(linda_send) | |||
309 | { | 309 | { |
310 | // change status of lane to "waiting" | 310 | // change status of lane to "waiting" |
311 | prev_status = lane->m_status; // Running, most likely | 311 | prev_status = lane->m_status; // Running, most likely |
312 | LUA_ASSERT(L, prev_status == Lane::Running); // but check, just in case | 312 | LUA_ASSERT(L_, prev_status == Lane::Running); // but check, just in case |
313 | lane->m_status = Lane::Waiting; | 313 | lane->m_status = Lane::Waiting; |
314 | LUA_ASSERT(L, lane->m_waiting_on == nullptr); | 314 | LUA_ASSERT(L_, lane->m_waiting_on == nullptr); |
315 | lane->m_waiting_on = &linda->m_read_happened; | 315 | lane->m_waiting_on = &linda->m_read_happened; |
316 | } | 316 | } |
317 | // could not send because no room: wait until some data was read before trying again, or until timeout is reached | 317 | // could not send because no room: wait until some data was read before trying again, or until timeout is reached |
@@ -331,26 +331,26 @@ LUAG_FUNC(linda_send) | |||
331 | 331 | ||
332 | if (!pushed.has_value()) | 332 | if (!pushed.has_value()) |
333 | { | 333 | { |
334 | raise_luaL_error(L, "tried to copy unsupported types"); | 334 | raise_luaL_error(L_, "tried to copy unsupported types"); |
335 | } | 335 | } |
336 | 336 | ||
337 | switch (cancel) | 337 | switch (cancel) |
338 | { | 338 | { |
339 | case CancelRequest::Soft: | 339 | case CancelRequest::Soft: |
340 | // if user wants to soft-cancel, the call returns lanes.cancel_error | 340 | // if user wants to soft-cancel, the call returns lanes.cancel_error |
341 | kCancelError.pushKey(L); | 341 | kCancelError.pushKey(L_); |
342 | return 1; | 342 | return 1; |
343 | 343 | ||
344 | case CancelRequest::Hard: | 344 | case CancelRequest::Hard: |
345 | // raise an error interrupting execution only in case of hard cancel | 345 | // raise an error interrupting execution only in case of hard cancel |
346 | raise_cancel_error(L); // raises an error and doesn't return | 346 | raise_cancel_error(L_); // raises an error and doesn't return |
347 | 347 | ||
348 | default: | 348 | default: |
349 | lua_pushboolean(L, ret); // true (success) or false (timeout) | 349 | lua_pushboolean(L_, ret); // true (success) or false (timeout) |
350 | return 1; | 350 | return 1; |
351 | } | 351 | } |
352 | }; | 352 | }; |
353 | return Linda::ProtectedCall(L, send); | 353 | return Linda::ProtectedCall(L_, send); |
354 | } | 354 | } |
355 | 355 | ||
356 | // ################################################################################################# | 356 | // ################################################################################################# |
@@ -368,22 +368,22 @@ LUAG_FUNC(linda_send) | |||
368 | */ | 368 | */ |
369 | LUAG_FUNC(linda_receive) | 369 | LUAG_FUNC(linda_receive) |
370 | { | 370 | { |
371 | auto receive = [](lua_State* L) | 371 | auto receive = [](lua_State* L_) |
372 | { | 372 | { |
373 | Linda* const linda{ ToLinda<false>(L, 1) }; | 373 | Linda* const linda{ ToLinda<false>(L_, 1) }; |
374 | std::chrono::time_point<std::chrono::steady_clock> until{ std::chrono::time_point<std::chrono::steady_clock>::max() }; | 374 | std::chrono::time_point<std::chrono::steady_clock> until{ std::chrono::time_point<std::chrono::steady_clock>::max() }; |
375 | int key_i{ 2 }; // index of first key, if timeout not there | 375 | int key_i{ 2 }; // index of first key, if timeout not there |
376 | 376 | ||
377 | if (lua_type(L, 2) == LUA_TNUMBER) // we don't want to use lua_isnumber() because of autocoercion | 377 | if (lua_type(L_, 2) == LUA_TNUMBER) // we don't want to use lua_isnumber() because of autocoercion |
378 | { | 378 | { |
379 | lua_Duration const duration{ lua_tonumber(L, 2) }; | 379 | lua_Duration const duration{ lua_tonumber(L_, 2) }; |
380 | if (duration.count() >= 0.0) | 380 | if (duration.count() >= 0.0) |
381 | { | 381 | { |
382 | until = std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(duration); | 382 | until = std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(duration); |
383 | } | 383 | } |
384 | ++key_i; | 384 | ++key_i; |
385 | } | 385 | } |
386 | else if (lua_isnil(L, 2)) // alternate explicit "infinite timeout" by passing nil before the key | 386 | else if (lua_isnil(L_, 2)) // alternate explicit "infinite timeout" by passing nil before the key |
387 | { | 387 | { |
388 | ++key_i; | 388 | ++key_i; |
389 | } | 389 | } |
@@ -391,39 +391,39 @@ LUAG_FUNC(linda_receive) | |||
391 | keeper_api_t selected_keeper_receive{ nullptr }; | 391 | keeper_api_t selected_keeper_receive{ nullptr }; |
392 | int expected_pushed_min{ 0 }, expected_pushed_max{ 0 }; | 392 | int expected_pushed_min{ 0 }, expected_pushed_max{ 0 }; |
393 | // are we in batched mode? | 393 | // are we in batched mode? |
394 | kLindaBatched.pushKey(L); | 394 | kLindaBatched.pushKey(L_); |
395 | int const is_batched{ lua501_equal(L, key_i, -1) }; | 395 | int const is_batched{ lua501_equal(L_, key_i, -1) }; |
396 | lua_pop(L, 1); | 396 | lua_pop(L_, 1); |
397 | if (is_batched) | 397 | if (is_batched) |
398 | { | 398 | { |
399 | // no need to pass linda.batched in the keeper state | 399 | // no need to pass linda.batched in the keeper state |
400 | ++key_i; | 400 | ++key_i; |
401 | // make sure the keys are of a valid type | 401 | // make sure the keys are of a valid type |
402 | check_key_types(L, key_i, key_i); | 402 | check_key_types(L_, key_i, key_i); |
403 | // receive multiple values from a single slot | 403 | // receive multiple values from a single slot |
404 | selected_keeper_receive = KEEPER_API(receive_batched); | 404 | selected_keeper_receive = KEEPER_API(receive_batched); |
405 | // we expect a user-defined amount of return value | 405 | // we expect a user-defined amount of return value |
406 | expected_pushed_min = (int) luaL_checkinteger(L, key_i + 1); | 406 | expected_pushed_min = (int) luaL_checkinteger(L_, key_i + 1); |
407 | expected_pushed_max = (int) luaL_optinteger(L, key_i + 2, expected_pushed_min); | 407 | expected_pushed_max = (int) luaL_optinteger(L_, key_i + 2, expected_pushed_min); |
408 | // don't forget to count the key in addition to the values | 408 | // don't forget to count the key in addition to the values |
409 | ++expected_pushed_min; | 409 | ++expected_pushed_min; |
410 | ++expected_pushed_max; | 410 | ++expected_pushed_max; |
411 | if (expected_pushed_min > expected_pushed_max) | 411 | if (expected_pushed_min > expected_pushed_max) |
412 | { | 412 | { |
413 | raise_luaL_error(L, "batched min/max error"); | 413 | raise_luaL_error(L_, "batched min/max error"); |
414 | } | 414 | } |
415 | } | 415 | } |
416 | else | 416 | else |
417 | { | 417 | { |
418 | // make sure the keys are of a valid type | 418 | // make sure the keys are of a valid type |
419 | check_key_types(L, key_i, lua_gettop(L)); | 419 | check_key_types(L_, key_i, lua_gettop(L_)); |
420 | // receive a single value, checking multiple slots | 420 | // receive a single value, checking multiple slots |
421 | selected_keeper_receive = KEEPER_API(receive); | 421 | selected_keeper_receive = KEEPER_API(receive); |
422 | // we expect a single (value, key) pair of returned values | 422 | // we expect a single (value, key) pair of returned values |
423 | expected_pushed_min = expected_pushed_max = 2; | 423 | expected_pushed_min = expected_pushed_max = 2; |
424 | } | 424 | } |
425 | 425 | ||
426 | Lane* const lane{ kLanePointerRegKey.readLightUserDataValue<Lane>(L) }; | 426 | Lane* const lane{ kLanePointerRegKey.readLightUserDataValue<Lane>(L_) }; |
427 | Keeper* const K{ linda->whichKeeper() }; | 427 | Keeper* const K{ linda->whichKeeper() }; |
428 | KeeperState const KL{ K ? K->L : nullptr }; | 428 | KeeperState const KL{ K ? K->L : nullptr }; |
429 | if (KL == nullptr) | 429 | if (KL == nullptr) |
@@ -447,16 +447,16 @@ LUAG_FUNC(linda_receive) | |||
447 | } | 447 | } |
448 | 448 | ||
449 | // all arguments of receive() but the first are passed to the keeper's receive function | 449 | // all arguments of receive() but the first are passed to the keeper's receive function |
450 | pushed = keeper_call(linda->U, KL, selected_keeper_receive, L, linda, key_i); | 450 | pushed = keeper_call(linda->U, KL, selected_keeper_receive, L_, linda, key_i); |
451 | if (!pushed.has_value()) | 451 | if (!pushed.has_value()) |
452 | { | 452 | { |
453 | break; | 453 | break; |
454 | } | 454 | } |
455 | if (pushed.value() > 0) | 455 | if (pushed.value() > 0) |
456 | { | 456 | { |
457 | LUA_ASSERT(L, pushed.value() >= expected_pushed_min && pushed.value() <= expected_pushed_max); | 457 | LUA_ASSERT(L_, pushed.value() >= expected_pushed_min && pushed.value() <= expected_pushed_max); |
458 | // replace sentinels with real nils | 458 | // replace sentinels with real nils |
459 | keeper_toggle_nil_sentinels(L, lua_gettop(L) - pushed.value(), LookupMode::FromKeeper); | 459 | keeper_toggle_nil_sentinels(L_, lua_gettop(L_) - pushed.value(), LookupMode::FromKeeper); |
460 | // To be done from within the 'K' locking area | 460 | // To be done from within the 'K' locking area |
461 | // | 461 | // |
462 | linda->m_read_happened.notify_all(); | 462 | linda->m_read_happened.notify_all(); |
@@ -475,9 +475,9 @@ LUAG_FUNC(linda_receive) | |||
475 | { | 475 | { |
476 | // change status of lane to "waiting" | 476 | // change status of lane to "waiting" |
477 | prev_status = lane->m_status; // Running, most likely | 477 | prev_status = lane->m_status; // Running, most likely |
478 | LUA_ASSERT(L, prev_status == Lane::Running); // but check, just in case | 478 | LUA_ASSERT(L_, prev_status == Lane::Running); // but check, just in case |
479 | lane->m_status = Lane::Waiting; | 479 | lane->m_status = Lane::Waiting; |
480 | LUA_ASSERT(L, lane->m_waiting_on == nullptr); | 480 | LUA_ASSERT(L_, lane->m_waiting_on == nullptr); |
481 | lane->m_waiting_on = &linda->m_write_happened; | 481 | lane->m_waiting_on = &linda->m_write_happened; |
482 | } | 482 | } |
483 | // not enough data to read: wakeup when data was sent, or when timeout is reached | 483 | // not enough data to read: wakeup when data was sent, or when timeout is reached |
@@ -496,25 +496,25 @@ LUAG_FUNC(linda_receive) | |||
496 | 496 | ||
497 | if (!pushed.has_value()) | 497 | if (!pushed.has_value()) |
498 | { | 498 | { |
499 | raise_luaL_error(L, "tried to copy unsupported types"); | 499 | raise_luaL_error(L_, "tried to copy unsupported types"); |
500 | } | 500 | } |
501 | 501 | ||
502 | switch (cancel) | 502 | switch (cancel) |
503 | { | 503 | { |
504 | case CancelRequest::Soft: | 504 | case CancelRequest::Soft: |
505 | // if user wants to soft-cancel, the call returns kCancelError | 505 | // if user wants to soft-cancel, the call returns kCancelError |
506 | kCancelError.pushKey(L); | 506 | kCancelError.pushKey(L_); |
507 | return 1; | 507 | return 1; |
508 | 508 | ||
509 | case CancelRequest::Hard: | 509 | case CancelRequest::Hard: |
510 | // raise an error interrupting execution only in case of hard cancel | 510 | // raise an error interrupting execution only in case of hard cancel |
511 | raise_cancel_error(L); // raises an error and doesn't return | 511 | raise_cancel_error(L_); // raises an error and doesn't return |
512 | 512 | ||
513 | default: | 513 | default: |
514 | return pushed.value(); | 514 | return pushed.value(); |
515 | } | 515 | } |
516 | }; | 516 | }; |
517 | return Linda::ProtectedCall(L, receive); | 517 | return Linda::ProtectedCall(L_, receive); |
518 | } | 518 | } |
519 | 519 | ||
520 | // ################################################################################################# | 520 | // ################################################################################################# |
@@ -529,12 +529,12 @@ LUAG_FUNC(linda_receive) | |||
529 | */ | 529 | */ |
530 | LUAG_FUNC(linda_set) | 530 | LUAG_FUNC(linda_set) |
531 | { | 531 | { |
532 | auto set = [](lua_State* L) | 532 | auto set = [](lua_State* L_) |
533 | { | 533 | { |
534 | Linda* const linda{ ToLinda<false>(L, 1) }; | 534 | Linda* const linda{ ToLinda<false>(L_, 1) }; |
535 | bool const has_value{ lua_gettop(L) > 2 }; | 535 | bool const has_value{ lua_gettop(L_) > 2 }; |
536 | // make sure the key is of a valid type (throws an error if not the case) | 536 | // make sure the key is of a valid type (throws an error if not the case) |
537 | check_key_types(L, 2, 2); | 537 | check_key_types(L_, 2, 2); |
538 | 538 | ||
539 | Keeper* const K{ linda->whichKeeper() }; | 539 | Keeper* const K{ linda->whichKeeper() }; |
540 | KeeperCallResult pushed; | 540 | KeeperCallResult pushed; |
@@ -543,12 +543,12 @@ LUAG_FUNC(linda_set) | |||
543 | if (has_value) | 543 | if (has_value) |
544 | { | 544 | { |
545 | // convert nils to some special non-nil sentinel in sent values | 545 | // convert nils to some special non-nil sentinel in sent values |
546 | keeper_toggle_nil_sentinels(L, 3, LookupMode::ToKeeper); | 546 | keeper_toggle_nil_sentinels(L_, 3, LookupMode::ToKeeper); |
547 | } | 547 | } |
548 | pushed = keeper_call(linda->U, K->L, KEEPER_API(set), L, linda, 2); | 548 | pushed = keeper_call(linda->U, K->L, KEEPER_API(set), L_, linda, 2); |
549 | if (pushed.has_value()) // no error? | 549 | if (pushed.has_value()) // no error? |
550 | { | 550 | { |
551 | LUA_ASSERT(L, pushed.value() == 0 || pushed.value() == 1); | 551 | LUA_ASSERT(L_, pushed.value() == 0 || pushed.value() == 1); |
552 | 552 | ||
553 | if (has_value) | 553 | if (has_value) |
554 | { | 554 | { |
@@ -558,7 +558,7 @@ LUAG_FUNC(linda_set) | |||
558 | if (pushed.value() == 1) | 558 | if (pushed.value() == 1) |
559 | { | 559 | { |
560 | // the key was full, but it is no longer the case, tell writers they should wake | 560 | // the key was full, but it is no longer the case, tell writers they should wake |
561 | LUA_ASSERT(L, lua_type(L, -1) == LUA_TBOOLEAN && lua_toboolean(L, -1) == 1); | 561 | LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TBOOLEAN && lua_toboolean(L_, -1) == 1); |
562 | linda->m_read_happened.notify_all(); // To be done from within the 'K' locking area | 562 | linda->m_read_happened.notify_all(); // To be done from within the 'K' locking area |
563 | } | 563 | } |
564 | } | 564 | } |
@@ -566,14 +566,14 @@ LUAG_FUNC(linda_set) | |||
566 | else // linda is cancelled | 566 | else // linda is cancelled |
567 | { | 567 | { |
568 | // do nothing and return lanes.cancel_error | 568 | // do nothing and return lanes.cancel_error |
569 | kCancelError.pushKey(L); | 569 | kCancelError.pushKey(L_); |
570 | pushed.emplace(1); | 570 | pushed.emplace(1); |
571 | } | 571 | } |
572 | 572 | ||
573 | // must trigger any error after keeper state has been released | 573 | // must trigger any error after keeper state has been released |
574 | return OptionalValue(pushed, L, "tried to copy unsupported types"); | 574 | return OptionalValue(pushed, L_, "tried to copy unsupported types"); |
575 | }; | 575 | }; |
576 | return Linda::ProtectedCall(L, set); | 576 | return Linda::ProtectedCall(L_, set); |
577 | } | 577 | } |
578 | 578 | ||
579 | // ################################################################################################# | 579 | // ################################################################################################# |
@@ -585,17 +585,17 @@ LUAG_FUNC(linda_set) | |||
585 | */ | 585 | */ |
586 | LUAG_FUNC(linda_count) | 586 | LUAG_FUNC(linda_count) |
587 | { | 587 | { |
588 | auto count = [](lua_State* L) | 588 | auto count = [](lua_State* L_) |
589 | { | 589 | { |
590 | Linda* const linda{ ToLinda<false>(L, 1) }; | 590 | Linda* const linda{ ToLinda<false>(L_, 1) }; |
591 | // make sure the keys are of a valid type | 591 | // make sure the keys are of a valid type |
592 | check_key_types(L, 2, lua_gettop(L)); | 592 | check_key_types(L_, 2, lua_gettop(L_)); |
593 | 593 | ||
594 | Keeper* const K{ linda->whichKeeper() }; | 594 | Keeper* const K{ linda->whichKeeper() }; |
595 | KeeperCallResult const pushed{ keeper_call(linda->U, K->L, KEEPER_API(count), L, linda, 2) }; | 595 | KeeperCallResult const pushed{ keeper_call(linda->U, K->L, KEEPER_API(count), L_, linda, 2) }; |
596 | return OptionalValue(pushed, L, "tried to count an invalid key"); | 596 | return OptionalValue(pushed, L_, "tried to count an invalid key"); |
597 | }; | 597 | }; |
598 | return Linda::ProtectedCall(L, count); | 598 | return Linda::ProtectedCall(L_, count); |
599 | } | 599 | } |
600 | 600 | ||
601 | // ################################################################################################# | 601 | // ################################################################################################# |
@@ -607,35 +607,35 @@ LUAG_FUNC(linda_count) | |||
607 | */ | 607 | */ |
608 | LUAG_FUNC(linda_get) | 608 | LUAG_FUNC(linda_get) |
609 | { | 609 | { |
610 | auto get = [](lua_State* L) | 610 | auto get = [](lua_State* L_) |
611 | { | 611 | { |
612 | Linda* const linda{ ToLinda<false>(L, 1) }; | 612 | Linda* const linda{ ToLinda<false>(L_, 1) }; |
613 | lua_Integer const count{ luaL_optinteger(L, 3, 1) }; | 613 | lua_Integer const count{ luaL_optinteger(L_, 3, 1) }; |
614 | luaL_argcheck(L, count >= 1, 3, "count should be >= 1"); | 614 | luaL_argcheck(L_, count >= 1, 3, "count should be >= 1"); |
615 | luaL_argcheck(L, lua_gettop(L) <= 3, 4, "too many arguments"); | 615 | luaL_argcheck(L_, lua_gettop(L_) <= 3, 4, "too many arguments"); |
616 | // make sure the key is of a valid type (throws an error if not the case) | 616 | // make sure the key is of a valid type (throws an error if not the case) |
617 | check_key_types(L, 2, 2); | 617 | check_key_types(L_, 2, 2); |
618 | 618 | ||
619 | KeeperCallResult pushed; | 619 | KeeperCallResult pushed; |
620 | if (linda->simulate_cancel == CancelRequest::None) | 620 | if (linda->simulate_cancel == CancelRequest::None) |
621 | { | 621 | { |
622 | Keeper* const K{ linda->whichKeeper() }; | 622 | Keeper* const K{ linda->whichKeeper() }; |
623 | pushed = keeper_call(linda->U, K->L, KEEPER_API(get), L, linda, 2); | 623 | pushed = keeper_call(linda->U, K->L, KEEPER_API(get), L_, linda, 2); |
624 | if (pushed.value_or(0) > 0) | 624 | if (pushed.value_or(0) > 0) |
625 | { | 625 | { |
626 | keeper_toggle_nil_sentinels(L, lua_gettop(L) - pushed.value(), LookupMode::FromKeeper); | 626 | keeper_toggle_nil_sentinels(L_, lua_gettop(L_) - pushed.value(), LookupMode::FromKeeper); |
627 | } | 627 | } |
628 | } | 628 | } |
629 | else // linda is cancelled | 629 | else // linda is cancelled |
630 | { | 630 | { |
631 | // do nothing and return lanes.cancel_error | 631 | // do nothing and return lanes.cancel_error |
632 | kCancelError.pushKey(L); | 632 | kCancelError.pushKey(L_); |
633 | pushed.emplace(1); | 633 | pushed.emplace(1); |
634 | } | 634 | } |
635 | // an error can be raised if we attempt to read an unregistered function | 635 | // an error can be raised if we attempt to read an unregistered function |
636 | return OptionalValue(pushed, L, "tried to copy unsupported types"); | 636 | return OptionalValue(pushed, L_, "tried to copy unsupported types"); |
637 | }; | 637 | }; |
638 | return Linda::ProtectedCall(L, get); | 638 | return Linda::ProtectedCall(L_, get); |
639 | } | 639 | } |
640 | 640 | ||
641 | // ################################################################################################# | 641 | // ################################################################################################# |
@@ -648,38 +648,38 @@ LUAG_FUNC(linda_get) | |||
648 | */ | 648 | */ |
649 | LUAG_FUNC(linda_limit) | 649 | LUAG_FUNC(linda_limit) |
650 | { | 650 | { |
651 | auto limit = [](lua_State* L) | 651 | auto limit = [](lua_State* L_) |
652 | { | 652 | { |
653 | Linda* const linda{ ToLinda<false>(L, 1) }; | 653 | Linda* const linda{ ToLinda<false>(L_, 1) }; |
654 | // make sure we got 3 arguments: the linda, a key and a limit | 654 | // make sure we got 3 arguments: the linda, a key and a limit |
655 | luaL_argcheck( L, lua_gettop( L) == 3, 2, "wrong number of arguments"); | 655 | luaL_argcheck( L_, lua_gettop( L_) == 3, 2, "wrong number of arguments"); |
656 | // make sure we got a numeric limit | 656 | // make sure we got a numeric limit |
657 | luaL_checknumber( L, 3); | 657 | luaL_checknumber( L_, 3); |
658 | // make sure the key is of a valid type | 658 | // make sure the key is of a valid type |
659 | check_key_types( L, 2, 2); | 659 | check_key_types( L_, 2, 2); |
660 | 660 | ||
661 | KeeperCallResult pushed; | 661 | KeeperCallResult pushed; |
662 | if (linda->simulate_cancel == CancelRequest::None) | 662 | if (linda->simulate_cancel == CancelRequest::None) |
663 | { | 663 | { |
664 | Keeper* const K{ linda->whichKeeper() }; | 664 | Keeper* const K{ linda->whichKeeper() }; |
665 | pushed = keeper_call(linda->U, K->L, KEEPER_API(limit), L, linda, 2); | 665 | pushed = keeper_call(linda->U, K->L, KEEPER_API(limit), L_, linda, 2); |
666 | LUA_ASSERT(L, pushed.has_value() && (pushed.value() == 0 || pushed.value() == 1)); // no error, optional boolean value saying if we should wake blocked writer threads | 666 | LUA_ASSERT(L_, pushed.has_value() && (pushed.value() == 0 || pushed.value() == 1)); // no error, optional boolean value saying if we should wake blocked writer threads |
667 | if (pushed.value() == 1) | 667 | if (pushed.value() == 1) |
668 | { | 668 | { |
669 | LUA_ASSERT(L, lua_type( L, -1) == LUA_TBOOLEAN && lua_toboolean( L, -1) == 1); | 669 | LUA_ASSERT(L_, lua_type( L_, -1) == LUA_TBOOLEAN && lua_toboolean( L_, -1) == 1); |
670 | linda->m_read_happened.notify_all(); // To be done from within the 'K' locking area | 670 | linda->m_read_happened.notify_all(); // To be done from within the 'K' locking area |
671 | } | 671 | } |
672 | } | 672 | } |
673 | else // linda is cancelled | 673 | else // linda is cancelled |
674 | { | 674 | { |
675 | // do nothing and return lanes.cancel_error | 675 | // do nothing and return lanes.cancel_error |
676 | kCancelError.pushKey(L); | 676 | kCancelError.pushKey(L_); |
677 | pushed.emplace(1); | 677 | pushed.emplace(1); |
678 | } | 678 | } |
679 | // propagate pushed boolean if any | 679 | // propagate pushed boolean if any |
680 | return pushed.value(); | 680 | return pushed.value(); |
681 | }; | 681 | }; |
682 | return Linda::ProtectedCall(L, limit); | 682 | return Linda::ProtectedCall(L_, limit); |
683 | } | 683 | } |
684 | 684 | ||
685 | // ################################################################################################# | 685 | // ################################################################################################# |
@@ -691,10 +691,10 @@ LUAG_FUNC(linda_limit) | |||
691 | */ | 691 | */ |
692 | LUAG_FUNC(linda_cancel) | 692 | LUAG_FUNC(linda_cancel) |
693 | { | 693 | { |
694 | Linda* const linda{ ToLinda<false>(L, 1) }; | 694 | Linda* const linda{ ToLinda<false>(L_, 1) }; |
695 | char const* who = luaL_optstring(L, 2, "both"); | 695 | char const* who = luaL_optstring(L_, 2, "both"); |
696 | // make sure we got 3 arguments: the linda, a key and a limit | 696 | // make sure we got 3 arguments: the linda, a key and a limit |
697 | luaL_argcheck(L, lua_gettop(L) <= 2, 2, "wrong number of arguments"); | 697 | luaL_argcheck(L_, lua_gettop(L_) <= 2, 2, "wrong number of arguments"); |
698 | 698 | ||
699 | linda->simulate_cancel = CancelRequest::Soft; | 699 | linda->simulate_cancel = CancelRequest::Soft; |
700 | if (strcmp(who, "both") == 0) // tell everyone writers to wake up | 700 | if (strcmp(who, "both") == 0) // tell everyone writers to wake up |
@@ -716,7 +716,7 @@ LUAG_FUNC(linda_cancel) | |||
716 | } | 716 | } |
717 | else | 717 | else |
718 | { | 718 | { |
719 | raise_luaL_error(L, "unknown wake hint '%s'", who); | 719 | raise_luaL_error(L_, "unknown wake hint '%s'", who); |
720 | } | 720 | } |
721 | return 0; | 721 | return 0; |
722 | } | 722 | } |
@@ -735,8 +735,8 @@ LUAG_FUNC(linda_cancel) | |||
735 | */ | 735 | */ |
736 | LUAG_FUNC(linda_deep) | 736 | LUAG_FUNC(linda_deep) |
737 | { | 737 | { |
738 | Linda* const linda{ ToLinda<false>(L, 1) }; | 738 | Linda* const linda{ ToLinda<false>(L_, 1) }; |
739 | lua_pushlightuserdata(L, linda); // just the address | 739 | lua_pushlightuserdata(L_, linda); // just the address |
740 | return 1; | 740 | return 1; |
741 | } | 741 | } |
742 | 742 | ||
@@ -751,9 +751,9 @@ LUAG_FUNC(linda_deep) | |||
751 | */ | 751 | */ |
752 | 752 | ||
753 | template <bool OPT> | 753 | template <bool OPT> |
754 | [[nodiscard]] static int LindaToString(lua_State* L, int idx_) | 754 | [[nodiscard]] static int LindaToString(lua_State* L_, int idx_) |
755 | { | 755 | { |
756 | Linda* const linda{ ToLinda<OPT>(L, idx_) }; | 756 | Linda* const linda{ ToLinda<OPT>(L_, idx_) }; |
757 | if (linda != nullptr) | 757 | if (linda != nullptr) |
758 | { | 758 | { |
759 | char text[128]; | 759 | char text[128]; |
@@ -762,7 +762,7 @@ template <bool OPT> | |||
762 | len = sprintf(text, "Linda: %.*s", (int) sizeof(text) - 8, linda->getName()); | 762 | len = sprintf(text, "Linda: %.*s", (int) sizeof(text) - 8, linda->getName()); |
763 | else | 763 | else |
764 | len = sprintf(text, "Linda: %p", linda); | 764 | len = sprintf(text, "Linda: %p", linda); |
765 | lua_pushlstring(L, text, len); | 765 | lua_pushlstring(L_, text, len); |
766 | return 1; | 766 | return 1; |
767 | } | 767 | } |
768 | return 0; | 768 | return 0; |
@@ -770,7 +770,7 @@ template <bool OPT> | |||
770 | 770 | ||
771 | LUAG_FUNC(linda_tostring) | 771 | LUAG_FUNC(linda_tostring) |
772 | { | 772 | { |
773 | return LindaToString<false>(L, 1); | 773 | return LindaToString<false>(L_, 1); |
774 | } | 774 | } |
775 | 775 | ||
776 | // ################################################################################################# | 776 | // ################################################################################################# |
@@ -786,21 +786,21 @@ LUAG_FUNC(linda_concat) | |||
786 | { // linda1? linda2? | 786 | { // linda1? linda2? |
787 | bool atLeastOneLinda{ false }; | 787 | bool atLeastOneLinda{ false }; |
788 | // Lua semantics enforce that one of the 2 arguments is a Linda, but not necessarily both. | 788 | // Lua semantics enforce that one of the 2 arguments is a Linda, but not necessarily both. |
789 | if (LindaToString<true>(L, 1)) | 789 | if (LindaToString<true>(L_, 1)) |
790 | { | 790 | { |
791 | atLeastOneLinda = true; | 791 | atLeastOneLinda = true; |
792 | lua_replace(L, 1); | 792 | lua_replace(L_, 1); |
793 | } | 793 | } |
794 | if (LindaToString<true>(L, 2)) | 794 | if (LindaToString<true>(L_, 2)) |
795 | { | 795 | { |
796 | atLeastOneLinda = true; | 796 | atLeastOneLinda = true; |
797 | lua_replace(L, 2); | 797 | lua_replace(L_, 2); |
798 | } | 798 | } |
799 | if (!atLeastOneLinda) // should not be possible | 799 | if (!atLeastOneLinda) // should not be possible |
800 | { | 800 | { |
801 | raise_luaL_error(L, "internal error: linda_concat called on non-Linda"); | 801 | raise_luaL_error(L_, "internal error: linda_concat called on non-Linda"); |
802 | } | 802 | } |
803 | lua_concat(L, 2); | 803 | lua_concat(L_, 2); |
804 | return 1; | 804 | return 1; |
805 | } | 805 | } |
806 | 806 | ||
@@ -812,12 +812,12 @@ LUAG_FUNC(linda_concat) | |||
812 | */ | 812 | */ |
813 | LUAG_FUNC(linda_dump) | 813 | LUAG_FUNC(linda_dump) |
814 | { | 814 | { |
815 | auto dump = [](lua_State* L) | 815 | auto dump = [](lua_State* L_) |
816 | { | 816 | { |
817 | Linda* const linda{ ToLinda<false>(L, 1) }; | 817 | Linda* const linda{ ToLinda<false>(L_, 1) }; |
818 | return keeper_push_linda_storage(*linda, DestState{ L }); | 818 | return keeper_push_linda_storage(*linda, DestState{ L_ }); |
819 | }; | 819 | }; |
820 | return Linda::ProtectedCall(L, dump); | 820 | return Linda::ProtectedCall(L_, dump); |
821 | } | 821 | } |
822 | 822 | ||
823 | // ################################################################################################# | 823 | // ################################################################################################# |
@@ -828,12 +828,12 @@ LUAG_FUNC(linda_dump) | |||
828 | */ | 828 | */ |
829 | LUAG_FUNC(linda_towatch) | 829 | LUAG_FUNC(linda_towatch) |
830 | { | 830 | { |
831 | Linda* const linda{ ToLinda<false>(L, 1) }; | 831 | Linda* const linda{ ToLinda<false>(L_, 1) }; |
832 | int pushed{ keeper_push_linda_storage(*linda, DestState{ L }) }; | 832 | int pushed{ keeper_push_linda_storage(*linda, DestState{ L_ }) }; |
833 | if (pushed == 0) | 833 | if (pushed == 0) |
834 | { | 834 | { |
835 | // if the linda is empty, don't return nil | 835 | // if the linda is empty, don't return nil |
836 | pushed = LindaToString<false>(L, 1); | 836 | pushed = LindaToString<false>(L_, 1); |
837 | } | 837 | } |
838 | return pushed; | 838 | return pushed; |
839 | } | 839 | } |
@@ -870,17 +870,17 @@ namespace global { | |||
870 | */ | 870 | */ |
871 | LUAG_FUNC(linda) | 871 | LUAG_FUNC(linda) |
872 | { | 872 | { |
873 | int const top{ lua_gettop(L) }; | 873 | int const top{ lua_gettop(L_) }; |
874 | luaL_argcheck(L, top <= 2, top, "too many arguments"); | 874 | luaL_argcheck(L_, top <= 2, top, "too many arguments"); |
875 | if (top == 1) | 875 | if (top == 1) |
876 | { | 876 | { |
877 | LuaType const t{ lua_type_as_enum(L, 1) }; | 877 | LuaType const t{ lua_type_as_enum(L_, 1) }; |
878 | luaL_argcheck(L, t == LuaType::STRING || t == LuaType::NUMBER, 1, "wrong parameter (should be a string or a number)"); | 878 | luaL_argcheck(L_, t == LuaType::STRING || t == LuaType::NUMBER, 1, "wrong parameter (should be a string or a number)"); |
879 | } | 879 | } |
880 | else if (top == 2) | 880 | else if (top == 2) |
881 | { | 881 | { |
882 | luaL_checktype(L, 1, LUA_TSTRING); | 882 | luaL_checktype(L_, 1, LUA_TSTRING); |
883 | luaL_checktype(L, 2, LUA_TNUMBER); | 883 | luaL_checktype(L_, 2, LUA_TNUMBER); |
884 | } | 884 | } |
885 | return LindaFactory::Instance.pushDeepUserdata(DestState{ L }, 0); | 885 | return LindaFactory::Instance.pushDeepUserdata(DestState{ L_ }, 0); |
886 | } | 886 | } |